通过泛型投射

问题描述 投票:4回答:1

有没有办法转换对象以返回方法的通用值?我试过这种方式但发生了Casting异常:

public <S extends Super> S get(Class<S> clazz) {
    return (S) new Super();
}

public class Super {

}

public class Sub1 extends Super {

}

public class Sub2 extends Super {

}

例外:

java.lang.ClassCastException: 
Cannot cast com.zarinak.app.model.Super to com.zarinak.app.model.Sub1

有办法吗?

java android generics casting generic-programming
1个回答
5
投票

您尝试将新Super对象强制转换为已扩展它的对象类型的方式不正确。

假设您要创建一个Sub1对象 - 使用Super类中的构造函数实例化一个Super对象,然后告诉编译器该对象实际上是Sub1,它不是;它既不包含Sub1特定的方法或变量,也不使用Sub1构造函数构造。编译器知道该对象不是Sub1,并且会在运行时抛出错误。虽然这可能不是代码当前结构的问题,但是当Sub1包含Super不包含的方法或变量时,它将成为问题。如果编译器允许这种形式的转换,那么尝试在轨道上调用这些方法将是一个重要问题。

这将实现你想要的。通过将S泛型类型约束为Super的扩展,您可以有效地绕过实例化Super对象并从那里进行强制转换。

public <S extends Super> S get(Class<S> clazz) throws IllegalAccessException, InstantiationException {
    S s = clazz.newInstance();
    return s;
}

将此作为一种方法,没有任何额外的身体,几乎完全没有意义,你也可以称之为clazz.newInstance()。但是,这确实确保了对象的类扩展了Super。

© www.soinside.com 2019 - 2024. All rights reserved.