Java 7 方法调用中的钻石操作
这是讨论的后续问题:
为什么菱形运算符在 Java 7 中的 addAll() 调用中不起作用?
来自 Java 教程,
http://docs.oracle.com/javase/tutorial/java/generics/ gentypeinference.html
请注意,菱形通常在方法调用中起作用;但是,为了更清楚起见,建议您主要使用菱形来初始化声明的变量
所以,我对第一行有点困惑。钻石何时在方法调用中起作用?
关于钻石运算符如何工作的更多解释可以在这里找到:
由此,我尝试了以下方法,效果很好:
假设我有:
private static class Box<T>{
public Box(T t){}
}
static void f(Box<Integer> box){}
像下面这样的调用可以很好地编译:
f(new Box<>(new Integer(10)));
上面的 f()
方法调用中调用构造函数的类型参数从构造函数的参数推断出来(即Integer
)。
这就是教程所说的意思吗
请注意,菱形通常在方法调用中起作用
如果没有,任何人都可以提供一个钻石在方法调用中起作用的示例吗?
This is kind of a follow up question on the discussion:
Why doesn't the diamond operator work within a addAll() call in Java 7?
From the Java Tutorial,
http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html
Note that the diamond often works in method calls; however, for greater clarity, it is suggested that you use the diamond primarily to initialize a variable where it is declared
So, I am a bit confused about the first line. When does diamond work in method calls?
A bit more explanation on how diamond operator works can be found here:
And from this, I have tried the following, which works fine:
Give that I have:
private static class Box<T>{
public Box(T t){}
}
static void f(Box<Integer> box){}
a call like the following compiles fine:
f(new Box<>(new Integer(10)));
The type parameter in invoking the constructor in the method call of f()
above is inferred from the argument to the constructor (i.e. Integer
).
So is this what is meant when the tutorial says
Note that the diamond often works in method calls
If not, can anyone kind enough to provide an example where diamond works in method call?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
,尽管在
<>
运算符方面存在一些问题。在您的情况下,Box 实例化不是问题,因为可以使用构造函数参数轻松推断出类型。尝试将构造函数更改为“不”接受
Integer
或T
并查看调用如何失败。同样,看看这个类:
同样,链接问题中的问题(关于 addAll )可以通过帮助编译器简单地解决,如下所示:
Diamond 运算符似乎也会中断实现匿名类如下:
幸运的是,在这种情况下,编译器非常明确地提到
<>
不适用于匿名类。I think yes though there are a couple of gotchas when it comes to
<>
operators.In your case, Box instantiation is a non-issue given that the type can be trivially inferred using the constructor argument. Try changing the constructor to "not" take in an
Integer
orT
and see how the invocation fails.Similarly, have a look at this class:
Similarly, the problem in your linked question (regarding
addAll
) can be simply solved by helping out the compiler a bit as follows:Diamond operators also seem to break when it comes to implementing anonymous classes as follows:
Fortunately, in this case, the compiler is pretty explicit in mentioning that
<>
doesn't/won't work with anonymous classes.我认为不值得考虑什么时候有效、什么时候无效。编译器会告诉你,因此你必须重写那些不起作用的内容。
其背后并没有真正的理由;这更像是开发人员将特定时间实际编译器实现的当前限制放入规范中,并告诉我们:事情必须如此。
Java 8 消除了许多这些限制,而且没有完全冻结。例如,
用 Java 8 编译没有任何错误。而且,为什么不呢?
I don’t think that it is worth thinking about when it works and when not. The compiler will tell you and thus you have to rewrite what’s not working.
There is not a real rationale behind it; it’s more like the developers have put the current limitations of the actual compiler’s implementation at a specific time into the specification and told us: that’s how it has to be.
Java 8 lifts a lot of these limitations without the hell freezing over. E.g.
compiles with Java 8 without any error. And, why not?
这实际上与方法调用无关。独立语句
也可以编译。有足够的信息来推断
Box
的T
(即从 Integer 参数)另一方面,这不能编译
没有办法知道列表是什么类型想要的。
这是有效的,因为目标类型有助于推理
Collection
It's not really about method invocation. The standalone statement
also compiles. There are enough information to infer
T
forBox
(i.e. from the Integer argument)On the other hand, this doesn't compile
There's no way to know what kind of list is desired.
this works because inference is helped by the target type
Collection<String>