I was surprised, but ... this compiles:
public <T extends Database> ColMetaData<T>[] getTableColumnsAsEnums() {
Class<? extends ColMetaData> cls = this.columnsEnumToken();
return cls.<ColMetaData<T>[]>getEnumConstants(); }
Here is the method for columnsEnumToken:
// Returns a class token for an enum class
public Class<? extends ColMetaData> columnsEnumToken() {
return this.e_colsToken;
}
(I guess I can see why the second line below doesn't compile)
Some questions:
Is this method "type safe"?
Why does this line compile:
Class<? extends ColMetaData> cls = this.columnsEnumToken();
But this one fails to compile because of incompatible types:
Class<? extends ColMetaData<T>> cls = this.columnsEnumToken();
Why is it legal for method getTableColumnsAsEnums()
to return an array of a concrete parameterized type, ColMetaData<T>[]
. I had thought that these were strictly verboten because there was no runtime way to have them operate type safely.
Java allows generic classes, methods, etc. that can be declared independent of types. However, Java does not allow the array to be generic. The reason for this is that in Java, arrays contain information related to their components and this information is used to allocate memory at runtime.
Using generics, primitive types can not be passed as type parameters. In the example given below, if we pass int primitive type to box class, then compiler will complain. To mitigate the same, we need to pass the Integer object instead of int primitive type.
Array of generic typesNo, we cannot create an array of generic type objects if you try to do so, a compile time error is generated.
Class
Theoretically, a Class cannot represent a parameterized type. For example, there is no class for List<String>
, so you should not write Class<List<String>>
, but only Class<List>
.
However Class<? extends List<String>>
could make sense. For example, if we have
public class MyStringList extends ArrayList<String>{}
MyStringList.class
is a Class<MyStringList>
which is a Class<? extends List<String>>
Generic Array
There's nothing wrong with generic array type, it's just that Java forbids us to instantiate any... But the reason isn't very convincing. You can just go ahead and create one through casts, as long as you know it's safe.
Actually, there is a straightforward way in Java to create a generic array. When we call a method with varargs X...
, an X[]
object will be created - and X can be any type.
Compatible assignment
Apparently for some backward compatibility reason, we can assign a List[]
to List<String>[]
. That's why you can return a ColMetaData[]
object while the return type is ColMetaData<T>[]
.
Think about what ColMetaData<T>[]
represents. In Java, generics are strictly a compile time issue. At run time, they cease to exist. So what you're really telling the runtime is that you have an array of ColMetaData
instances, which indeed is a concrete type. This is different, however, than using an arbitrary type for the array. The array type is still ColMetaData
, and Java can determine this at compile time. Then the compiler needs only to track that the instances you store use the correct generic type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With