1

让我们有以下类:

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)
    }
}

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

  1. 构造函数返回值的默认类型是真的void吗?
  2. 构造函数之后的 from 类型擦除是否public <E> MyClass(E e){ System.out.println(e.toString);}等同于public MyClass(Object o){ System.out.println(o.toString);}?
4

1 回答 1

8

构造函数的返回值的默认类型是否为 void?

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

JVM 规范第 2.9 节

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

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

构造函数之后的 from 类型擦除是否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);}

因为最左边的边界E现在是一个Integer.


参考:

于 2013-10-06T10:56:02.527 回答