Nik*_*ris 2 java generics methods class return-type
我有一个Generic Class Factory类,它有两个方法,一个使用Class泛型T值,另一个只使用自己的方法泛型定义.
public class GenericClassFactory<T extends ClassMatchable> {
public <E, K> E newObject(ClassMatcher<E, K> matcher, K key, String packageName){...}
public <K> T newObject(K key, String packageName){...}
}
Run Code Online (Sandbox Code Playgroud)
使用T通用的方法工作正常,但是当我想使用其他不关心T泛型的方法时,它将不会使用Generic E它只返回一个Object然后我必须输入它.
Data data = new GenericClassFactory().newObject(new ClassMatcher<Data, String>(){...}, "key1", "my.package.name.impl");
Run Code Online (Sandbox Code Playgroud)
这有编译错误,因为它要我将其类型转换为(Data).如果我将GenericClassFactory传递给一个有效的Class Generic它将会起作用.如果您定义了Class Generic但未使用它,则它无法识别方法泛型.
Data data = new GenericClassFactory<ClassMatchable>().newObject(new ClassMatcher<Data, String>(){...}, "key1", "my.package.name.impl");
Run Code Online (Sandbox Code Playgroud)
这很好.但是,当我的目的不需要时,我必须定义一个类泛型,这是愚蠢的.我能做到这一点:
public class GenericClassFactory {
public <E, K> E newObject(ClassMatcher<E, K> matcher, K key, String packageName){...}
public <T extends ClassMatchable, K> T newObject(K key, String packageName){...}
}
Run Code Online (Sandbox Code Playgroud)
但是现在我的第二种方法似乎太宽泛或者某种东西......也许不是.我的意思是,如果要分配给返回类型的对象未实现ClassMatchable,它仍会产生编译错误.那是我应该去的方式吗?这样我就不必进行类型转换?
这是正确的,如果你不输入类引用,那么即使只使用方法类型参数的泛型方法也不会被泛化.这是Java Generics的一个奇怪的细微差别.如你所说,你可以输入一些任意类型T:
Data data = new GenericClassFactory<ClassMatchable>().newObject(new ClassMatcher<Data, String>(){...}, "key1", "my.package.name.impl");
Run Code Online (Sandbox Code Playgroud)
但更有可能这甚至不应该是实例方法.它不能是静态方法吗?如果是这样,您可以像这样调用它:
Data data = GenericClassFactory.newObject(new ClassMatcher<Data, String>(){...}, "key1", "my.package.name.impl");
Run Code Online (Sandbox Code Playgroud)
请注意,这扩展到所有实例成员,而不仅仅是通用实例方法.因此,有更简单的案例证明了这种奇怪的细微差别.此代码仅编译警告:
public class Scratchpad<T> {
List<String> list;
public static void main(String[] args) {
Scratchpad sp = new Scratchpad();
List<Integer> list = sp.list;
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为sp.list虽然与a 无关,但却被解决为a List,而不是a .List<String> Scratchpad.listT
这在JLS第4.8节中详细记录:
未从其超类或超接口继承的原始类型C 的构造函数(第8.8节),实例方法(第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是其类型的擦除在对应于C的泛型声明中.原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同.
| 归档时间: |
|
| 查看次数: |
1029 次 |
| 最近记录: |