类型参数G隐藏类型G.

时间:2015-09-28 09:53:26

标签: java generics

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设计中的一个错误吗?

3 个答案:

答案 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,但您无法确定Xint的超类型。从技术上讲,这可以通过<X super Integer>完成,但我不确定这实际上是您正在寻找的。

答案 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;
}