我们有以下课程:
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)
}
}
众所周知,当我们创建一个新的类实例时,首先调用这个类的方法,调用构造函数。 问题:
void
吗? public <E> MyClass(E e){ System.out.println(e.toString);}
之后的类型擦除是否等同于public MyClass(Object o){ System.out.println(o.toString);}
?答案 0 :(得分:8)
默认情况下,构造函数的返回值类型是否为void?
您不会向构造函数提供任何显式返回类型。但是,构造函数在内部转换为名为non-static
的{{1}}方法,其返回类型为<init>
。
在Java虚拟机的级别上,用Java编程语言(JLS§8.8)编写的每个
void
都显示为具有特殊名称{{1的实例初始化方法 }}。该名称由编译器提供。由于名称constructor
不是有效的标识符,因此不能直接在使用Java编程语言编写的程序中使用。 实例初始化方法只能通过<init>
指令(§invokespecial)在Java虚拟机中调用,并且只能在未初始化的类实例上调用它们。实例初始化方法接受从其派生的构造函数的访问权限(JLS§6.6)。
同样,静态初始化程序在内部转换为<init>
方法 - invokespecial
,同样返回类型为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);}
的最左边界现在是public MyClass(Integer e){ System.out.println(e.toString);}
。
<强>参考文献:强>