我创建了一个抽象类Foo。现在我想要上述通用类的String实现。但是运行代码时出现ClassCast Exception。
public abstract class Foo<T> {
abstract void add(T ... elements); //warning :Type safety: Potential heap pollution via varargs parameter elements
void addUnlessNull(T ... elements) //warning :Type safety: Potential heap pollution via varargs parameter elements
{
for(T element:elements)
{
if(element!=null)
add(element); // Warning:Type safety: A generic array of T is created for a varargs parameter
}
}
}
public class StringFoo extends Foo<String> {
private List<String> list=new ArrayList<>();
@Override
void add(String... elements) {
list.addAll(Arrays.asList(elements));
}
public static void main(String[] args)
{
StringFoo ss=new StringFoo();
ss.addUnlessNull("Hello","World"); //Class Cast Exception
}
}
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at StringFoo.add(StringFoo.java:1)
at Foo.addUnlessNull(Foo.java:10)
at StringFoo.main(StringFoo.java:19)
我不确定为什么,但我想我知道原因。当您调用时add(element)
,会element
被打包Object[] { element }
,然后传递给add
方法。所以有一个ClassCastException
从Object[]
到String[]
。
下面是一个不好的解决方案,但是应该可以解决您的问题。
if(element != null) {
Object arr = Array.newInstance(element.getClass(), 1);
Array.set(arr, 0, element);
add((T[]) arr);
}
我已经在JDK 10上进行了测试ClassCastException
,上面还有一个代码可以消除此异常。
我写了一个简单的例子,它也会产生ClassCastException
:
abstract class A<T> {
public void test(T t) { f(t); }
public abstract void f(T... ts);
}
class B extends A<String> {
@Override
public void f(String[] s) {}
public static void main(String[] args) {
new B().test("");
}
}
我使用反射检查了B的方法,有三种相关方法:
public void B.f(java.lang.Object[])
public void B.f(java.lang.String[])
public void A.test(java.lang.Object)
当我打电话时new B().test("")
,它会打电话public void A.test(java.lang.Object)
。然后f(t)
,在此方法中调用,而实际上将调用public void B.f(java.lang.Object[])
。这是因为t
被视为Object
(尽管是String
)。因此t
打包成Object[]
而不是String[]
。但是,类中的实际方法B
是public void B.f(java.lang.String[])
,因此存在ClassCastException
。
我不确定我是否理解正确,无法在JLS中找到某些内容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句