嗨检查以下代码
ArrayList x=new ArrayList();
ArrayList<String>y=x;
ArrayList<StringBuffer>z=x;
y.add("Strings");
System.out.println(z.get(0).toString());
我在System.out.println
获得了类强制转换异常 java.lang.ClassCastException: java.lang.String
at com.one.MainClass.main(MainClass.java:16)
但是当我在尝试时
System.out.println(z.get(0))
它正在运作 为什么会这样?
答案 0 :(得分:2)
我认为你是在做这个实验(如果没有,那么请阅读其他答案,了解你应该如何编写代码)。
x是原始ArrayList
,您可以在其中放置任何类型的对象。
y.add("string")
添加一个字符串。
z是ArrayList<StringBuffer>
并且需要StringBuffers。当您调用z.get(0)
时,JVM会在返回之前尝试将索引为0的元素转换为StringBuffer。那个演员失败了。
换句话说,虽然StringBuffer s = z.get(0);
编译,但它会在运行时抛出ClassCastException,因为z.get(0)
不是StringBuffer
。
答案 1 :(得分:1)
您遇到问题的具体细节是:
为避免这种情况,请不要为String和StringBuffer键入数组。只选一个。例如:
ArrayList<StringBuffer> myArrayList = new ArrayList<StringBuffer>
如果要将String arraylist复制到StringBuffer ArrayList中,则必须遍历z中的所有项目以将它们转换为字符串缓冲区:
ArrayList x=new ArrayList();
ArrayList<String>y=x;
ArrayList<StringBuffer>z=new ArrayList<StringBuffer>();
for(String s : y)
z.add(new StringBuffer(s));
原因是StringBuffer没有扩展String。造成问题的原因是你不能投射一个字符串,比如说“str”到一个StringBuffer,即你不能StringBuffer s = (StringBuffer)"str";
。
要将ArrayList x
投射到ArrayList<T>
,x
的所有元素都必须扩展或是T
的实例。
此外,如果可能,您应始终使用泛型类型。如果您不知道列表中的内容(例如),请使用:
ArrayList<?> x = new ArrayList<?>();
如果您知道更多,例如它将是另一个类的子类,请使用
ArrayList<? extends T>
或ArrayList<? implements T>
。这将有助于您避免将来的ClassCastExceptions。