ClassCast异常:子类实现在调用超类方法时抛出异常

时间:2018-08-05 06:11:30

标签: java generics

我创建了一个抽象类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)

1 个答案:

答案 0 :(得分:1)

我不确定为什么,但是我想我知道原因。调用invoke时, func (t *SampleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response. 被打包到add(element)中,然后传递给element方法。因此,从Object[] { element }add有一个ClassCastException

下面是一个不好的解决方案,但是应该可以解决您的问题。

Object[]

我已经在JDK 10上进行了测试,仍然有一个String[],上面的代码可以消除此异常。

更新

我写了一个简单的示例,该示例也会产生if(element != null) { Object arr = Array.newInstance(element.getClass(), 1); Array.set(arr, 0, element); add((T[]) arr); }

ClassCastException

我用反射检查了B的方法,有三种相关方法:

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(""); } } 时,它将呼叫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

我不确定我是否理解正确,无法在JLS中找到某些内容。