猿问

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

我创建了一个抽象类 Foo 。现在我想要一个上述通用类的字符串实现。但是当我运行代码时我得到了一个 ClassCast 异常。


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)


拉丁的传说
浏览 116回答 1
1回答

繁花如伊

我不知道为什么,但我想我知道原因。当您调用 时add(element), 将element被打包Object[] { element }并传递给add方法。所以有一个ClassCastExceptionfrom Object[]to String[]。以下是一个不好的解决方案,但它应该可以解决您的问题。if(element != null) {&nbsp; &nbsp; Object arr = Array.newInstance(element.getClass(), 1);&nbsp; &nbsp; Array.set(arr, 0, element);&nbsp; &nbsp; add((T[]) arr);}我在JDK 10上测试过,还有一个ClassCastException,上面的代码可以消除这个异常。更新我写了一个简单的例子,它也会产生ClassCastException:abstract class A<T> {&nbsp; &nbsp; public void test(T t) { f(t); }&nbsp;&nbsp; &nbsp; public abstract void f(T... ts);}class B extends A<String> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public void f(String[] s) {}&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; new B().test("");&nbsp; &nbsp; }}我用反射检查了B的方法,有3个相关的方法: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 中找到某些内容。
随时随地看视频慕课网APP

相关分类

Java
我要回答