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:
这是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();
类 cls = this.columnsEnumToken();
But this one fails to compile because of incompatible types:
但由于类型不兼容,这个无法编译:
Class<? extends ColMetaData<T>> cls = this.columnsEnumToken();
类 > 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.为什么方法getTableColumnsAsEnums()返回具体参数化类型的数组ColMetaData
[]是合法的。我曾经认为这些是严格禁止的,因为没有运行时方式让它们安全地操作类型。
2 个解决方案
#1
2
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>
.
从理论上讲,Class不能表示参数化类型。例如,List
>,而只能编写Class
。
However Class<? extends List<String>>
could make sense. For example, if we have
然而Class >可能有意义。例如,如果我们有
public class MyStringList extends ArrayList<String>{}
MyStringList.class
is a Class<MyStringList>
which is a Class<? extends List<String>>
MyStringList.class是一个Class
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.
通用数组类型没有任何问题,只是Java禁止我们实例化任何......但原因并不是很有说服力。只要您知道它是安全的,您就可以继续创建一个通过演员阵容。
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.
实际上,Java中有一种直接的方法来创建通用数组。当我们使用varargs X ...调用方法时,将创建一个X []对象 - 而X可以是任何类型。
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>[]
.
显然出于某些向后兼容的原因,我们可以将List []分配给List
#2
1
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.
想想ColMetaData
#1
2
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>
.
从理论上讲,Class不能表示参数化类型。例如,List
>,而只能编写Class
。
However Class<? extends List<String>>
could make sense. For example, if we have
然而Class >可能有意义。例如,如果我们有
public class MyStringList extends ArrayList<String>{}
MyStringList.class
is a Class<MyStringList>
which is a Class<? extends List<String>>
MyStringList.class是一个Class
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.
通用数组类型没有任何问题,只是Java禁止我们实例化任何......但原因并不是很有说服力。只要您知道它是安全的,您就可以继续创建一个通过演员阵容。
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.
实际上,Java中有一种直接的方法来创建通用数组。当我们使用varargs X ...调用方法时,将创建一个X []对象 - 而X可以是任何类型。
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>[]
.
显然出于某些向后兼容的原因,我们可以将List []分配给List
#2
1
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.
想想ColMetaData