如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗?
考虑以下示例:
public class MyClass {
public K doSomething(K k){
return k;
}
}
public class MyGenericClass {
public K doSomething(K k){
return k;
}
public List makeSingletonList(K k){
return Collections.singletonList(k);
}
}
正如您对通用方法所期望的那样,我可以使用任何对象调用doSomething(K)的实例MyClass:
MyClass clazz = new MyClass();
String string = clazz.doSomething("String");
Integer integer = clazz.doSomething(1);
但是,如果我尝试使用MyGenericClass 不
指定泛型类型的实例,则无论传入什么,我都会调用doSomething(K)返回Object,K
MyGenericClass untyped = new MyGenericClass();
// this doesn't compile - "Incompatible types. Required: String, Found: Object"
String string = untyped.doSomething("String");
奇怪的是,如果返回类型是通用类,它将编译List(例如(实际上,这可以解释-参见下面的答案)):
MyGenericClass untyped = new MyGenericClass();
List list = untyped.makeSingletonList("String"); // this compiles
此外,如果输入通用类,即使仅使用通配符,它也会编译:
MyGenericClass> wildcard = new MyGenericClass();
String string = wildcard.doSomething("String"); // this compiles
有充分的理由为什么在无类型的泛型类中调用泛型方法不起作用?
是否存在一些与通用类和通用方法相关的巧妙技巧?
编辑:
为了明确起见,我希望未类型化或未类型化的泛型类不接受泛型类的类型参数(因为尚未提供)。但是,我不清楚为什么未类型化或原始类型的泛型类将意味着不遵循泛型方法。
可以看出,此问题已在SO上提出,请参见此问题。对此的答案说明,当一个类未类型化/以其原始格式时, 所有 泛型都将从该类中删除-包括泛型方法的键入。
但是,关于这种情况的原因,并没有真正的解释。因此,请允许我澄清我的问题:
Java为什么要删除无类型或原始类型的通用类上的通用方法类型?是否有充分的理由,还是仅仅是疏忽?
编辑-JLS的讨论:
已经建议(作为对先前的SO问题和对此问题的回答)在JLS
4.8中对此进行了处理,其中指出:
未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型为对应的原始类型在与C对应的通用声明中删除其类型。
对我来说,这很明显与无类型的类有什么关系-类的泛型被替换为擦除类型。如果类的泛型是绑定的,则擦除类型对应于那些边界。如果它们未绑定,则擦除类型为对象-例如
// unbound class types
public class MyGenericClass {
public T doSomething(T t) { return t; }
}
MyGenericClass untyped = new MyGenericClass();
Object t = untyped.doSomething("String");
// bound class types
public class MyBoundedGenericClass {
public T doSomething(T t) { return t; }
}
MyBoundedGenericClass bounded = new MyBoundedGenericClass();
Object t1 = bounded.doSomething("String"); // does not compile
Number t2 = bounded.doSomething(1); // does compile
尽管通用方法是实例方法,但我不清楚JLS
4.8是否适用于通用方法。通用方法的类型(在前面的示例中)不是未类型化的,因为它的类型是由方法参数确定的-只有类是未类型化/原始类型的。