err*_*ist 15 java generics inheritance abstract-class
我长期以来在Java中使用一个成语来在其(通常是抽象的)祖先类(es)的方法中使用(非抽象)类的类信息(遗憾的是我找不到这个模式的名称):
public abstract class Abstract<T extends Abstract<T>> {
private final Class<T> subClass;
protected Abstract(Class<T> subClass) {
this.subClass = subClass;
}
protected T getSomethingElseWithSameType() {
....
}
}
Run Code Online (Sandbox Code Playgroud)
其子类的示例:
public class NonGeneric extends Abstract<NonGeneric> {
public NonGeneric() {
super(NonGeneric.class);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我在定义其子类Abstract有自己的泛型参数时遇到了问题:
public class Generic<T> extends Abstract<Generic<T>> {
public Generic() {
super(Generic.class);
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子不可编译; 同样,不可能使用例如Generic<T>.class甚至使用通配符来指定泛型类型Generic<?>.
我也尝试将超T类中泛型类型的声明替换为? extends T,但这也不可编译.
有没有办法让这个模式与泛型基类一起使用?
Boh*_*ian 11
传递Class<T>(通常是构造函数)实例的"模式"(惯用法)是使用类文字作为运行时类型标记,并用于保持对泛型类型的运行时引用,否则将被擦除.
解决方案首先是将绑定的令牌类更改为:
Class<? extends T>
Run Code Online (Sandbox Code Playgroud)
然后像你对超类一样对你的泛型子类提出类似的要求; 让具体类传递一个类型标记,但您可以将其正确输入为参数:
这些类在没有强制转换或警告的情况下编译:
public abstract class Abstract<T extends Abstract<T>> {
private final Class<? extends T> subClass;
protected Abstract(Class<? extends T> subClass) {
this.subClass = subClass;
}
}
public class NonGeneric extends Abstract<NonGeneric> {
public NonGeneric() {
super(NonGeneric.class);
}
}
public class Generic<T> extends Abstract<Generic<T>> {
public Generic(Class<? extends Generic<T>> clazz) {
super(clazz);
}
}
Run Code Online (Sandbox Code Playgroud)
最后在具体类中,如果将声明用作自己的类,则不需要在任何地方使用强制转换:
public class IntegerGeneric extends Generic<Integer> {
public IntegerGeneric() {
super(IntegerGeneric.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我没有想出如何在没有强制转换的情况下创建Generic(匿名或非匿名)实例:
// can someone fill in the parameters without a cast?
new Generic<Integer>(???); // typed direct instance
new Generic<Integer>(???) { }; // anonymous
Run Code Online (Sandbox Code Playgroud)
我不认为这是可能的,但我欢迎以其他方式表现出来.