【发布时间】:2016-12-26 04:06:52
【问题描述】:
当下面的代码运行时:
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
class A {
private static final List<Adapter<? extends Number>> adapters = Arrays.asList(
Integer::valueOf,
s -> Long.valueOf(s),
(Adapter<Float>) s -> Float.valueOf(s),
new Adapter<Double>() {
@Override
public Double adapt(String s) {
return Double.valueOf(s);
}
}
);
private interface Adapter<T> {
T adapt(String s);
default Type type() {
try {
return getClass().getMethod("adapt", String.class).getReturnType();
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
}
public static void main(String[] args) {
for (Adapter<?> adapter : adapters) {
System.out.printf("Got adapter for type %s%n",
adapter.type().getTypeName());
}
}
}
我明白了:
% javac A.java
% java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
% java A
Got adapter for type java.lang.Object
Got adapter for type java.lang.Object
Got adapter for type java.lang.Object
Got adapter for type java.lang.Double
我很好奇为什么只有最后一个适配器被识别为 Double,其余的是 Object(而不是 Integer、Long 和 Float)。至少,我预计他们会支持 Number。
【问题讨论】:
-
有趣的问题...可能与编译器捕获泛型类型的方式有关。
-
查找这个的地方是在 JLS。希望这里有人知道从哪里引用。
标签: java generics lambda java-8