通用构造函数

St.*_*rio 1 java generics constructor

我们有以下课程:

public class MyClass<T>{
    public <E> MyClass(E e){ System.out.println(e.toString);}
}
public class Main{
    public static void main(String[] args){
        new MyClass(new String("string"));//will be invoked comstructor MyClass(Object)
    }
}
Run Code Online (Sandbox Code Playgroud)

众所周知,当我们创建一个新的类实例时,首先调用这个类的方法,调用构造函数.问题:

  1. 默认情况下,构造函数的返回值是否为真void
  2. 从类型擦除后,该构造函数public <E> MyClass(E e){ System.out.println(e.toString);}相当于public MyClass(Object o){ System.out.println(o.toString);}

Roh*_*ain 8

默认情况下,构造函数的返回值类型是否为空?

您不向构造函数提供任何显式返回类型.但是,构造函数在内部转换为返回类型为的non-static命名方法.<init>void

JVM规范第2.9节:

在Java虚拟机的级别上,每个constructor用Java编程语言编写的(JLS§8.8)都显示为具有特殊名称的实例初始化方法<init>.该名称由编译器提供.因为名称<init>不是有效的标识符,所以它不能直接用在用Java编程语言编写的程序中.实例初始化方法只能通过invokespecial指令(§invokespecial)在Java虚拟机中调用,并且它们只能在未初始化的类实例上调用.实例初始化方法采用从中派生的构造函数的访问权限(JLS§6.6).

类似地,静态初始值设定项在内部转换为static方法 - <clinit>同样具有返回类型void.

从类型擦除后,该构造函数public <E> MyClass(E e){ System.out.println(e.toString);}相当于public MyClass(Object o){ System.out.println(o.toString);}

是.类型参数的擦除是其最左边的边界.在这种情况下,由于没有约束E,擦除是Object.

你是否将你的构造函数声明为:

public <E extends Integer> MyClass(E e){ System.out.println(e.toString);}
Run Code Online (Sandbox Code Playgroud)

擦除这将是:

public MyClass(Integer e){ System.out.println(e.toString);}
Run Code Online (Sandbox Code Playgroud)

由于最左边的界限E现在是Integer.


参考文献:

  • (已经+1)看起来很不错:)百科全书,一如既往.不错的工作. (2认同)