JDC*_*JDC 18 java generics inheritance
我有以下课程:
class Field<T> {
private final Class<T> type;
public Field(Class<T> type) {
this.type = type;
}
}
class Pick<V> {
private final V value;
private final Class<V> type;
public Pick(V value, Class<V> type) {
this.value = value;
this.type = type;
}
}
Run Code Online (Sandbox Code Playgroud)
和问题所涉及的类:
class PickField<T> extends Field<Pick<T>> {
public PickField(Class<Pick<T>> type) {
super(type);
}
}
Run Code Online (Sandbox Code Playgroud)
现在这似乎被编译器接受了.不幸的是,我不知道/理解如何创建一个新的实例PickField,例如 String选择.
这当然 - 不起作用:
new PickField<String>(Pick.class)
这是不允许的(我想我理解为什么):
new PickField<String>(Pick<String>.class)
那怎么办呢?或者整个方法是否以某种方式" 闻 "?
Kon*_*kov 15
我认为PickField应该Pick只用实例参数化.
所以这样做应该没问题:
class PickField<T extends Pick<T>> extends Field<T> {
public PickField(Class<T> c) {
super(c);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下方法实例化它:
PickField<SomeSpecificPick> instance = new PickField<>(SomeSpecificPick.class);
Run Code Online (Sandbox Code Playgroud)
其中SomeSpecificPick定义为:
public class SomeSpecificPick extends Pick<SomeSpecificPick> {
public SomeSpecificPick(SomeSpecificPick value, Class<SomeSpecificPick> type) {
super(value, type);
}
}
Run Code Online (Sandbox Code Playgroud)
更多信息(与主题相关):
这里有各种各样的问题.
首先,正如您所指出的,您无法在编译时获取参数化类的类,因为只为通用类型编译了一个类,而不是每个给定类型参数编译一个类(例如,Pick<String>.class成语不编译,并且实际上没有意义).
再次提到,由于签名不匹配PickField<String>,因此Pick.class 仅使用参数化构造函数不会再次编译.
您可以使用运行时惯用法来推断正确的Pick<T>参数,但这会产生另一个问题:由于类型擦除,您的类型参数T将在运行时未知.
因此,您可以通过显式转换来参数化构造函数调用,如下所示:
new PickField<String>(
(Class<Pick<String>>)new Pick<String>("", String.class).getClass()
);
Run Code Online (Sandbox Code Playgroud)
...将使用"未经检查的强制转换"警告(Type safety: Unchecked cast from Class<capture#1-of ? extends Pick> to Class<Pick<String>>)进行编译.
在真正的问题可能是为什么你需要知道的价值type在你的Pick班级.
| 归档时间: |
|
| 查看次数: |
1103 次 |
| 最近记录: |