public class MyGenericClass< G> {
public <G> G genericMethod1(G g){
System.out.println(g.toString());
return g;
}
public <X> G genericMethod2(G g) {
System.out.println(g.toString());
return g;
}
public <X> X genericMethod3(G g) {
System.out.println(g.toString());
Integer i = new Integer(100);
return (X) i;
}
public static void main(String... cmdarg) {
MyGenericClass<Employee> gemp = new MyGenericClass<Employee>();
Employee e1 = new Employee();
e1.setName("My Name");
String resultOfMethod3 = gemp.genericMethod3(e1);
System.out.println(resultOfMethod3);
}
}
在genericMethod1中的:我得到编译器警告为&#34;类型参数G隐藏了类型G&#34;。
问题: 这个G隐藏哪个G?这是什么意思呢?
genericMethod2不会显示任何错误/警告。
问题: 我认为不应该编译。为什么在同一方法签名中允许两种不同的类型?什么是与G和X进行比较的典型实时示例?
在genericMethod3中:我故意返回一个Integer对象,而在main方法中我试图将结果赋给String。正如所料:我得到了ClassCastException。
问题:使用泛型来避免ClassCastExceptions的最初目的是什么?为什么编译器允许它?这是Generics设计中的一个错误吗?
答案 0 :(得分:5)
泛型可以在类级别和方法级别使用:
public class MyClass<T>
:T
可用于班级的所有实例成员(即非静态成员)(字段,方法,内部类......)public (static) <U> ReturnType myMethod(..) {...}
:U
仅适用于该方法你正在混合它们。
对于public <G> G genericMethod1(G g)
,此<G>
泛型隐藏了类'one',因为它们具有相同的名称,因此后者在方法中不再可用。如果要使用“泛型”类,请不要在方法级别指定它:public G genericMethod1(G g)
。
使用public <X> G genericMethod2(G g)
,您要定义未使用的通用<X>
:仅使用类'generic G
。
使用public <X> X genericMethod3(G g)
,您将定义用于方法返回值的通用<X>
。在方法正文中,您将int
转换为X
,但您无法确定X
是int
的超类型。从技术上讲,这可以通过<X super Integer>
完成,但我不确定这实际上是您正在寻找的。 p>
答案 1 :(得分:3)
public class MyGenericClass< G> {
public <G> G genericMethod1(G g){
System.out.println(g.toString());
return g;
}
这里有两个不同的<G>
变量,一个在类级别,另一个在方法级别。这大致相当于具有相同名称的字段和局部变量。本地变量将赢得&#34;赢得&#34;在这种情况下,就像方法级<G>
将覆盖类级别一样。由于这是导致错误的常见原因,因此IDE会向您发出警告。
方法2不会重新定义<G>
,因此不会产生任何警告。
答案 2 :(得分:0)
更改您的genericMethod1
,如下所示:
public G genericMethod1(G g){
System.out.println(g.toString());
return g;
}