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

Debapriya Biswas:

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

我不确定为什么,但我想我知道原因。当您调用时add(element),会element被打包Object[] { element },然后传递给add方法。所以有一个ClassCastExceptionObject[]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[]但是,类中的实际方法Bpublic void B.f(java.lang.String[]),因此存在ClassCastException

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Spring Security UsernamePasswordAuthenticationToken 在调用超类方法之前抛出异常

依靠超类抛出异常

从JAVA中的子类调用父类方法时引发Nullpointer异常

从超类调用子类方法

调用Spring数据方法时抛出奇怪的异常

异步方法是在调用时还是在等待时抛出异常?

实例化子类时从超类调用方法

在调用方法时获取扩展超类的子类实例

尽管捕获/处理了子类异常,但抛出父类异常强制抛出其子类异常事件?

抛出异常时类变为空

当类不需要抛出异常时

调用超类方法而不是子类方法

调用 Immutable.Map 子类的函数抛出 'xxx is not a function' 异常

当不覆盖子类中的抽象方法时,我不会抛出异常

枚举的JNI调用方法抛出异常

调用重写方法抛出经过检查的异常

Junit强制在方法调用时抛出异常

NSNotificationCenter从超类或子类调用方法?

如何使子类自动调用超类方法

当子类对象存储在超类数组中时,如何调用子类方法?

在方法而不是类上抛出异常

Java:抛出异常的类?

使用Java反射调用匿名类的方法时的访问异常

无法通过ManagementObjectCollection进行遍历,抛出“此方法未在任何类中实现”异常

检查方法的参数时是否抛出异常?

Matlab:当实现在超类中声明为抽象的方法时,为什么必须公开访问?

在子类的方法中本地调用超类方法时,使用“ super”关键字还是使用超类实例?

使用子类异常实现接口

当我尝试实现登录屏幕时抛出异常