public static <T extends String> void main(T[] args) {
System.out.println("Hello World!");
}
I was curious to see if the above snippet of code would compile and run successfully, and it does! However, I also wondered what would happen if T extends String
was replaced with T extends String & AutoClosable
; String
does not implement AutoClosable
, so I didn't expect this to run successfully, but it still does!
public static <T extends String & AutoCloseable> void main(T[] args) {
System.out.println("This still works!");
}
So my question is, why does this still run successfully?
Notes:
- I'm testing this with Java 10.0.1
- Intellij doesn't play nice with this method because it doesn't see it as an entry point to the program; I haven't tested it with other IDEs.
- You're also able to pass arguments using the command-line just as you would with any other program.
This is because a type parameter has a bound:
<T extends String> => String
<T extends String & AutoCloseable> => String & AutoCloseable
And the bytecode after erasure is the same as for the regular main
declaration in both cases:
public static main([Ljava/lang/String;)V
The order of types in a bound is only significant in that the erasure of a type variable is determined by the first type in its bound, and that a class type or type variable may only appear in the first position.