类型参数G隐藏类型G.

Jin*_*nah 3 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);                            

    }


}
Run Code Online (Sandbox Code Playgroud)

在genericMethod1:我得到编译器警告"类型参数G隐藏类型G".

问题: G隐藏哪个G?这是什么意思?

genericMethod2不显示任何错误/警告.

问题: 我认为不应该编译.为什么在同一方法签名中允许两种不同的类型?与G和X比较的典型实时示例是什么?

在genericMethod3中:我故意返回一个Integer对象,在main方法中我试图将结果赋给String.正如所料:我得到了ClassCastException.

问题:使用泛型来避免ClassCastExceptions不是最初的目的吗?为什么编译器允许它?这是泛型设计中的一个错误吗?

sp0*_*00m 5

泛型可以在类级别和方法级别使用:

  • public class MyClass<T>:T可用于类的所有实例成员(即非静态)(字段,方法,内部类......)
  • public (static) <U> ReturnType myMethod(..) {...}:U仅适用于该方法

你在搅拌它们.

有了public <G> G genericMethod1(G g),这个<G>泛型隐藏了类'一个,因为它们具有相同的名称,因此后者在方法中不再可用.如果要使用类'generic,请不要在方法级别指定它:public G genericMethod1(G g).

使用public <X> G genericMethod2(G g),您将定义<X>未使用的泛型:仅使用类'泛型G.

使用public <X> X genericMethod3(G g),您将定义<X>用于方法返回值的泛型.在方法体中,您正在转换intX但不能确定它X是超类型的int.从技术上讲,这可以用<X super Integer>,但我不确定这实际上是你在寻找什么.