T类如何以及何时从Integer变为String而不是显示错误/异常

Pra*_*kar 7 java generics incompatibletypeerror

我所做的就是了解Generics在Java中的工作原理.我写了以下代码:

public class Test {

    public static void main(String... args) throws Exception{  
        Foo o = new Foo<Integer>(new Integer(5));
        o.fun();
    }
}       

class Foo<T> {

    private T t;

    public Foo(T t) throws InstantiationException, IllegalAccessException{
       System.out.println("1. T is "+t.getClass());
       this.t = (T)"test";
       System.out.println("2. T is "+t.getClass());
   }

   void fun(){
       System.out.println("3. T is "+t.getClass()+" t = "+t);
   }
}
Run Code Online (Sandbox Code Playgroud)

输出是

1. T is class java.lang.Integer
2. T is Still class java.lang.Integer
3. T is class java.lang.String t = test
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么这会将Class从Integer更改为String而不显示错误/异常.

第二件事是,当我写信t = 9;function fun(),它显示:

incompatible types
required: T
found:    java.lang.Integer
Run Code Online (Sandbox Code Playgroud)

泛型类如何工作以及如何使用它们?

非常感谢您的回复!!

san*_*hat 4

您已声明一个没有上限的泛型。无界泛型的替换是Object它本身

这意味着,当生成类文件时,您的Foo<T>类看起来像这样

class Foo {

    private Object t;

    public Foo(Object  t) throws InstantiationException, IllegalAccessException{
       System.out.println("1. T is "+t.getClass());
       this.t = (Object)"test";
       System.out.println("2. T is "+t.getClass());
   }

   void fun(){
       System.out.println("3. T is "+t.getClass()+" t = "+t);
   }
}
Run Code Online (Sandbox Code Playgroud)

这是因为,泛型只是为了确保编译时类型安全。在运行时它们被擦除

考虑到这一点

this.t = (Object)"test";
Run Code Online (Sandbox Code Playgroud)

是一个有效的陈述,因为Object是所有类的超类,this.t然后就变成了String

的原因2. T is Still class java.lang.Integer

  • 这里t构造函数的一个参数,该参数仍然指向Integer(不被覆盖)
  • 并且该参数优先于this.t