Java中的ClassCastException错误:将Object[]转换为String[]

3

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)

我不知道如何修复这个问题。有人可以帮我解决一下吗?告诉我我做错了什么?

主要(BookMainKeeper类):

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());

}}

使用 BagInterface 的 pileBooks 类:

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
}

在 pileBooks 类中使用的 BagInterface:

 //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

1
你的 toArray() 方法生成了一个 Object[],而不是一个 String[] - Sotirios Delimanolis
你需要调用 toArray(new String[0])。如上所述,toArray() 返回 Object[]。 - kofemann
2个回答

1

你不能像将 Object 转换为 String 一样将 Object[] 转换为 String[]。你可能需要返回类型为 T 的实际数组。

如何实现呢?其中一种方法是在 toArray 中添加数组类型作为参数,例如:

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);

如果您确定数组只包含类型为T的对象,而不是其子类型,比如某种T1T2,那么您可以通过从存储的元素中读取来获取数组的类型。

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

但我认为第一种方法更好,因为它让你创建所需类型的数组,并消除了你会创建某种T1类型而不是T类型的数组的风险。


说实话,我不太理解你贴出来的代码……我该如何定义getClass()的内容,或者toArray(Class<T> clazz)是怎样工作的呢?我知道我是个新手…… - AndyApps
@AndyApps 每个对象都包含有关其类的信息。要在实时(程序运行时)中获取此信息,您可以使用 yourObject.getClass()。该方法将返回包含类的元信息的 Class 实例,例如类的完整名称、其字段的信息(可见性、类型、名称)、方法等等。通过这个对象和 java.lang.reflect.Array,您可以创建与类完全相同类型的数组 - 类似于 new SameClassAsPreviousObject[size] - Pshemo
所以在主函数中,我会使用类似于.toArray(pileBooks<String> x)的语法,而在toArray函数中,我会使用类似于reflect.Array的语法? - AndyApps
@AndyApps 在主函数中,你应该使用 String[] check = shelf2.toArray(String.class);,因为你想要返回 String[] 类型,并且使用我的第一个代码示例中的 toArray 方法。你需要添加实现来填充这个新数组以包含正确的内容。 - Pshemo
做到了,现在它可以正常工作了,它展示了我添加到书架1的三个书名,使用了shelf1.toArray而不是shelf2,因为它没有元素。 - AndyApps

0
你应该将它保存到一个对象数组中,而不是一个字符串数组中:
Object[] check = shelf1.toArray();

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

输出:

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

check 是一个对象数组。 Object 类是所有类的父类,包括 String。它在运行时进行检查,这就是为什么您的代码可以编译,但在执行期间会出现错误的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接