Mic*_*rry 20 java type-inference java-7
在Java 7及更高版本中,diamond可用于正常推断类型,因此没有问题:
List<String> list = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
但是,对于像这样的匿名内部类,它不能:
List<String> st = new List<>() { //Doesn't compile
//Implementation here
}
Run Code Online (Sandbox Code Playgroud)
为什么是这样?从逻辑上讲,在这种情况下,我可以将类型推断为String.这个决定的逻辑原因是,在匿名内部类中实际上不能推断出类型,还是由于其他原因而省略了?
在从stackoverflow跳过帖子后,google产生了http://mail.openjdk.java.net/pipermail/coin-dev/2011-June/003283.html
我猜是这样的,通常匿名类是表观类型的具体子类
interface Foo<N extends Number>
{
void foo(N n);
}
Foo<Integer> foo = new Foo<Integer>(){ ... }
Run Code Online (Sandbox Code Playgroud)
由
class AnonFoo_1 implements Foo<Integer>{ ... }
Foo<Integer> foo = new AnonFoo_1();
Run Code Online (Sandbox Code Playgroud)
假设我们允许对匿名类进行菱形推断,那么可能会出现复杂的情况,例如
Foo<? extends Runnable> foo = new Foo<>(){ ... }
Run Code Online (Sandbox Code Playgroud)
推理规则产生N=Number&Runnable; 遵循上一个实施技巧,我们需要
class AnonFoo_2 implements Foo<Number&Runnable>{ ... }
Run Code Online (Sandbox Code Playgroud)
目前不允许这样做;从arg到super类型的类型Foo必须是“普通”类型。
但是,理由不是很充分。我们可以发明其他实现技巧来使其工作
class AnonFoo<N extends Number&Runnable> implements Foo<N>
{
@Override public void foo(N n)
{
n.intValue();
n.run();
}
}
Foo<? extends Runnable> foo = new AnonFoo<>();
Run Code Online (Sandbox Code Playgroud)
编译器应该能够做同样的事情。
无论如何,至少编译器应允许大多数不涉及“不可表示类型”的用例,例如Foo<Integer> foo = new Foo<>(){...},很遗憾也禁止了这些常见/简单用例。
| 归档时间: |
|
| 查看次数: |
7635 次 |
| 最近记录: |