带通用参数的主要方法; 它为什么有效?

Jac*_* G. 35 java generics program-entry-point type-inference

public static <T extends String> void main(T[] args) {
    System.out.println("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)

我很想知道上面的代码片段是否可以编译并成功运行,而且确实如此!但是,我也想知道如果T extends String被替换会发生什么T extends String & AutoClosable; String没有实现AutoClosable,所以我没想到这会成功运行,但它仍然存在!

public static <T extends String & AutoCloseable> void main(T[] args) {
    System.out.println("This still works!");
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,为什么这仍然成功运行?

备注:

  • 我正在使用Java 10.0.1进行测试
  • Intellij对这种方法不好看,因为它不认为它是程序的入口点; 我没有用其他IDE测试过它.
  • 您也可以使用命令行传递参数,就像使用任何其他程序一样.

Ole*_*hov 31

这是因为类型参数有一个绑定:

<T extends String>                  =>  String

<T extends String & AutoCloseable>  =>  String & AutoCloseable
Run Code Online (Sandbox Code Playgroud)

擦除后的字节码与main两种情况下的常规声明相同:

public static main([Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)

JLS§4.4.类型变量:

绑定中类型的顺序仅在于,类型变量的擦除由其边界中的第一个类型确定,并且类类型或类型变量可能仅出现在第一个位置.

  • @ Li357只有第一个绑定有助于擦除类型. (4认同)
  • 有趣的是,在添加`args [0] .close();`和必需的`throws Exception`声明之后,程序仍然编译而没有任何警告,并且在运行时失败,因为`String`不能转换为`AutoCloseable`. (3认同)