AndyApps
AndyApps

Reputation: 57

ClassCastException in Java error Object[] to String[]

I get the error:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at Book.Organizer.Desk.RubCol.BookMainKeeper.main(BookMainKeeper.java:25)

I do not know how to fix this. Could anyone help me out by telling me what I'm doing wrong?

Main (BookMainKeeper class):

public class BookMainKeeper {

/**
 * @param args
 */
public static void main(String[] args) {

    BagInterface<String> shelf1 = new pileBooks<String>();
    BagInterface<String> shelf2 = new pileBooks<String>();
    BagInterface<String> shelf3 = new pileBooks<String>();

    shelf1.add("Java 3rd Edition");
    shelf1.add("Pre-Calculus 2nd Edition");
    shelf1.add("Lava World");

    String[] check = shelf2.toArray();

    System.out.println(shelf2.toArray());

}}

pileBooks class that uses BagInterface:

public class pileBooks<T> implements BagInterface<T> {

private final T[] bag; 
private static final int DEFAULT_CAPACITY = 25;
private int numberOfEntries;

/** Creates an empty bag whose initial capacity is 25. */
public pileBooks() 
{
    this(DEFAULT_CAPACITY);
} // end default constructor

/** Creates an empty bag having a given initial capacity.
@param capacity  the integer capacity desired */
public pileBooks(int capacity) 
{
    numberOfEntries = 0;
    // the cast is safe because the new array contains null entries
    @SuppressWarnings("unchecked")
    T[] tempBag = (T[])new Object[capacity]; // unchecked cast
    bag = tempBag;
} // end constructor

/**gets the current size of the bag
 * @return numberOfEntries
 */
public int getCurrentSize() {
    return numberOfEntries;
}

/** Sees whether this bag is full.
   @return true if this bag is full, or false if not */
public boolean isFull() 
{
    return numberOfEntries == bag.length;
} // end isFull

/**It checks if the bag is empty or not
 * @return True if numberOfEntries equals 0, False if otherwise
 */
public boolean isEmpty() {
    return numberOfEntries == 0;
}

/** Adds a new entry to this bag.
@param newEntry  the object to be added as a new entry
@return true if the addition is successful, or false if not */
public boolean add(T newEntry) 
{
    boolean result = true;
    if(isFull())
    {
        result = false;
    }
    else
    {
        bag[numberOfEntries]= newEntry;
        numberOfEntries++;
    }
    return result;
} // end add

/** Removes one unspecified entry from this bag, if possible.
   @return either the removed entry, if the removal
           was successful, or null */
    public T remove()
    {
        T result = null;
        if(numberOfEntries>0)
        {
            result = bag[numberOfEntries-1];
            bag[numberOfEntries - 1]=null;
            numberOfEntries--;
        }
        return result;
    } // end remove

/** Removes one occurrence of a given entry from this bag.
   @param anEntry  the entry to be removed
   @return true if the removal was successful, or false otherwise */
public boolean remove(T anEntry) 
{
    int index = getIndexOf(anEntry);
    T result = removeEntry(index);
    return anEntry.equals(result);
} // end remove

/**
 * Removes entry by verifying it's index
 * @param index = variable to check, if it is -1, the entry was not found
 * and it will exit, if it is 0 or higher, it means it was found in the bag
 * @return if index is -1, it returns result as null
 * if index is 0 or higher, it will put bag[index] in the variable result
 * and returns result
 */
protected T removeEntry(int index) {
    T result = null;
    int check = numberOfEntries;
    if(index != -1)
    {

        while((index < numberOfEntries) && ((check-1) != numberOfEntries)){



            if(index == (numberOfEntries-1))
            {
                result = bag[numberOfEntries-1];
                bag[numberOfEntries-1] = null;
                numberOfEntries--;
                break;
            }
            else
            {
                result = bag[index];
                bag[index] = bag [numberOfEntries-1];
                bag[numberOfEntries-1] = null;
                numberOfEntries--;
                break;
            }
        }
    }
    return result;
}



/**
 * verfifies if anEntry is inside the bag, if it is found, it assigns
 * i to the variable index
 * @param anEntry = object to search for inside the bag
 * @return index, -1 if anEntry was not found
 * whatever is contained in variable 'i' if it is found
 */
private int getIndexOf(T anEntry) {
    int index=-1;
    for(int i=0;i<bag.length;i++)
    {
        if(anEntry.equals(bag[i]))
        {
            index = i;
            break;
        }
    }
    return index;
}







/** Removes all entries from this bag. */
public void clear() 
{
    while(!isEmpty())
        remove();
} // end clear




/** Counts the number of times a given entry appears in this bag.
 @param anEntry  the entry to be counted
 @return the number of times anEntry appears in the bag */
public int getFrequencyOf(T anEntry) 
{
    int counter = 0;
    for(int index = 0; index < numberOfEntries; index++)
    {
        if (anEntry.equals(bag[index]))
        {
            counter++;
        }
    }
    return counter;
} // end getFrequencyOf






/** Tests whether this bag contains a given entry.
 @param anEntry  the entry to locate
 @return true if this bag contains anEntry, or false otherwise */
public boolean contains(T anEntry) 
{
    boolean found = false;
    for(int index = 0; !found && (index<numberOfEntries); index++)
    {
        if(anEntry.equals(bag[index]))
        {
            found = true;
        }
    }
    return found;
} // end contains






/** Retrieves all entries that are in this bag.
 @return a newly allocated array of all the entries in the bag */
public T[] toArray()
{
    //the cast is safe because the new array Contains null entries
    @SuppressWarnings("unchecked")
    T[] result = (T[])new Object[numberOfEntries];//unchecked cast
    for(int index=0;index < numberOfEntries; index++)
    {
        result[index]=bag[index];
    }
    return result;

} // end toArray
}

BagInterface used in pileBooks class :

 //An interface that describes the operations of a bag of objects.
 public interface BagInterface<T> {

 /** Gets the current number of entries in this bag.
 @return the integer number of entries currently in the bag */
 public int getCurrentSize();

 /** Sees whether this bag is full.
 @return true if the bag is full, or false if not */
 public boolean isFull();

 /** Sees whether this bag is empty.
 @return true if the bag is empty, or false if not */
 public boolean isEmpty();

 /** Adds a new entry to this bag.
 @param newEntry the object to be added as a new entry
 @ return true if the addition was successful, or false if not */
 public boolean add(T newEntry);

 /** Removes one unspecified entry from this bag, if possible.
 @return either the removed entry, if the removal was successful, or null */
 public T remove();

 /** Removes one occurrence of a given entry from this bag, if possible.
 @param anEntry the entry to be removed
 @return true if the removal was successful, or false if not */
 public boolean remove(T anEntry);

 /** Removes all entries from this bag. */
 public void clear();

 /** Counts the number of times a given entry appears in this bag.
 @param anEntry the entry to be counted
 @return the number of times anEntry appears in the bag */
 public int getFrequencyOf(T anEntry);

 /** Test whether this bag contains a given entry.
 @param anEntry the entry to locate
 @return true if the bag contains anEntry, or false otherwise */
 public boolean contains(T anEntry);

 /** Creates an array of all the entries that are in this bag.
 @return a newly allocated array of all entries in the bag */
 public T[] toArray();


 }// end BagInterface

Upvotes: 3

Views: 1337

Answers (2)

Jops
Jops

Reputation: 22715

You should save it into an Object array, instead of a String array:

Object[] check = shelf1.toArray();

System.out.println(check[1].toString());
System.out.println(check[2].toString());
System.out.println(check[3].toString());

Prints:

Java 3rd Edition
Pre-Calculus 2nd Edition
Lava World

check is an array of Objects. The Object class is the parent class of all classes, including String. It's checked during runtime, that's why your code compiles, but gets an error during execution.

Upvotes: 0

Pshemo
Pshemo

Reputation: 124225

You can't cast Object[] to String[] just like you cant cast Object to String. You will probably need to return real array of type T.

How to do this? One way is to add type of array as argument of toArray like

public T[] toArray(Class<T> clazz) {
    // the cast is safe because the new array Contains null entries
    @SuppressWarnings("unchecked")
    T[] result = (T[]) java.lang.reflect.Array.newInstance(clazz, numberOfEntries);

Or if you are sure that array will only contain objects of type T but not its subtypes like some kind of T1, T2 you can get type of array by reading it from one of stored elements like

T[] result = (T[]) java.lang.reflect.Array.newInstance(
        bag[0].getClass(), numberOfEntries);

but I would say that first way is better, since it let you create array of needed type, and eliminate risk that you will create array of some kind of T1 type instead of T.

Upvotes: 1

Related Questions