- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
假设我在 Java 中有这个:
List<String> list = new ArrayList<String>();
list.getClass();
最后一个表达式的类型是Class<? extends List>
.我明白为什么,由于删除,它不能是 Class<? extends List<String>>
.但是为什么不能是Class<? extends List<?>>
呢? ?
如果我想将这个表达式的结果分配给一个以某种方式保持该类实际上是某种类型的信息 List
?
Class<? extends List> listClass = list.getClass(); // raw type warning
Class<? extends List<?>> listClass = (Class<? extends List<?>>) list.getClass(); // unchecked cast warning
最佳答案
首次引入泛型时,getClass
返回 Class<? extends X>
, 其中X
是调用它的表达式的静态类型。此行为导致不合理的编译问题,如 this Oracle bug 中所报告.这是该错误报告的示例:
The following program fragment fails to compile
void f(List<Integer> li, List<String> ls) {
if (li.getClass() == ls.getClass())
;
}because the intersection of
Class<List<Integer>>
andClass<List<String>>
is empty.
此问题已通过扩大 getClass
的返回类型得到解决成为现在的样子。来自 the documentation :
The actual result type is
Class<? extends |X|>
where|X|
is the erasure of the static type of the expression on whichgetClass
is called.
这解决了上述问题,但最终导致了您的问题指出的问题。没多久,another bug据报道,争论如下:
I think the
getClass()
typing rule could be changed toClass<? extends
wildcard(T)>The wildcard operation is defined by: if
T
is parametrized,wildcard(T)=erasure(T)<?>
else ,wildcard(T)=T
JUSTIFICATION :
This rule introduce a raw type. Raw type must ONLY be used to interact with legacy code.
The new Rule introduce a wildcard. Relationship between parametrized type and wildcard are based on subtyping rules. Relationship between parametrized type and wildcard are based on raw type conversion.
这个错误没有得到解决,直到今天仍然开放,有以下反驳:
The proposal means that
getClass()
would return aClass<? extends
object, which is incompatible with other
ArrayList<?>>Class<? extends
objects. This is compatible with existing code like:
ArrayList<?>>List<String> l = ...;
Class<? extends List> c = l.getClass();because the new type of the RHS,
Class<? extends List<?>>
, is a subtype ofClass<? extends List>
.A disadvantage of enriching Class's type argument is that it will break idiomatic use of
Class.cast
. Today, you can write:List<Integer> x = ...;
Class<? extends List> cl = x.getClass();
List<Integer> y = cl.cast(null);and get a warning at
cast()
, because of the unchecked conversion fromList
toList<Integer>
. But with the proposal, the analogous code doesn't compile:List<Integer> x = ...;
Class<? extends List<?>> cl = x.getClass();
List<Integer> y = cl.cast(null);because
List<?>
returned bycast()
cannot be converted toList<Integer>
. The only way to avoid the error is to castcl.cast(..)
up toList
and suffer the unchecked conversion warning toList<Integer>
. This is effectively whatgetClass()
does already.Overall, the proposal seems like a good idea, but it has moderate complexity and a fairly small payoff.
(删节并更正了一些拼写错误)
关于java - 在 Java 中,在泛型实例上调用 getClass 时如何避免原始类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18782882/
我是一名优秀的程序员,十分优秀!