Java 7 中的链式调用?
我刚刚阅读了 Java 7 预览演示文稿 (pdf),其中有一张幻灯片链式调用。 这是幻灯片中使用的示例:
// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();
// Construction with chained invocation
Drink margarita = new DrinkBuilder()
.add("tequila")
.add("orange liqueur")
.add("lime juice")
.withRocks()
.withSalt()
.drink();
我对此百感交集。 不应将太多方法调用链接到一条语句中。 另一方面,编写 margarita.this()
和 margarita.that()
也不太方便。
现在,我从Delphi世界来到Java。 在Delphi中,有 with
语言构造。 这是少数人所珍视的,而许多人所厌恶的(或者是相反?)。 我发现 with
比链式调用的想法更优雅(我相信它的工作原理是 void
方法返回对其调用的对象的引用 - 并且这是我不喜欢的部分,因为 void
应该返回什么都)。
我希望 Java 采用 with
语言功能,因此示例代码可以这样编写:
Drink margarita = null;
with (new DrinkBuilder()) {
add("tequila");
add("orange liqueur");
add("lime juice");
withRocks();
withSalt();
margarita = drink();
}
我是唯一一个更喜欢这种解决方案而不是链式调用的人吗? 还有人认为 with
可能是 Java 语言的有用扩展吗? (让我想起有人关于“Java ++”需求的问题......)
I was just reading a Java 7 preview presentation (pdf) and there was a slide on Chained Invocation. Here is the example used in the slide:
// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();
// Construction with chained invocation
Drink margarita = new DrinkBuilder()
.add("tequila")
.add("orange liqueur")
.add("lime juice")
.withRocks()
.withSalt()
.drink();
And I have mixed feelings about this. One shouldn't chain too many method invocations into one statement. On the other hand, writing margarita.this()
and margarita.that()
isn't too convenient either.
Now, I am coming to Java from Delphi world. And in Delphi there is the with
language construct. This is cherished by a few and loathed by many (or is it the other way around?). I find with
to be more elegant than the idea of chained invocation (which I believe works on the basis of void
method returning reference to object on which it has been invoked - and this is the part I don't like, as void
should return nothing).
I would appreciate the with
language feature being adopted by Java, so the example code could be written like so:
Drink margarita = null;
with (new DrinkBuilder()) {
add("tequila");
add("orange liqueur");
add("lime juice");
withRocks();
withSalt();
margarita = drink();
}
Am I the only one who would prefer this solution to the chained invocation? Anyone else feels that with
could be a useful extension to Java language? (Reminds me of someone's question about the need of "Java++"...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
with 语句可以使用带有初始值设定项的匿名类在 Java 中进行翻译:
使用此习惯用法的缺点已有详细记录此处。
链接调用是方法链接的别名。 这是众所周知的习惯用法,适用于任何版本的 Java:
JDK 7 的建议是允许链接方法也适用于 void 返回类型:
the with statement can be translated in Java using anonymous classes with initializer:
the downsides of using this idiom are well documented here.
Chained Invocation is an alias for Method Chaining. That is well known idiom and works with any version of Java:
a proposal for JDK 7 is allowing of chaining method also for void return type:
这您可能感兴趣。
This might interest you.
我非常喜欢这种形式的
with
语句,但我更喜欢它们的 VB 版本:因为
With
块中的每个属性仍然必须前面有一个.< /code> 您知道您引用的是对象属性,而不是局部变量,从而减少了任何命名空间冲突。
如果我们以您的例子为例:
没有简单的方法来判断
withSalt()
是DrinkBuilder
的方法还是本地类中的方法。 如果您只允许在with
块中使用with
-ed 对象的方法,那么我认为它们的用处会大大降低。I quite like
with
statements of that form but I prefer the VB version of them:As each attribute in the
With
block still has to be preceded by a.
you know that you're referencing an Object property and not, say, a local variable, reducing any namespace collisions.If we take your example:
there's no easy way to tell if
withSalt()
is a method ofDrinkBuilder
or a method in local class. If you only allow methods of thewith
-ed object in thewith
block then I think they become much less useful.我不喜欢使用
with
; 我更喜欢 Pythonwith
语句。 不过,我确实同意您的观点,void
应该意味着void
。 在您提供的示例中,如果一个人确实希望能够链接方法调用,他们应该只更改其方法的返回类型,以便它们可以链接。I'm not a fan of this use of
with
; I much prefer the Pythonwith
statement. I do agree with you thatvoid
should meanvoid
, though. In the example you provide, if a person really wants to be able to chain method invocations they should just change the return types on their methods so they're chainable.也许对一个对象的多次调用是某些代码需要移动的标志?
Maybe the many many calls to one object are the sign that some code needs to be moved around?
Joshua Bloch 在 Effective Java 项目 #2 中强烈建议在以下情况下使用 Builder:有一个带有很多参数的构造函数。 原因之一是它可以被编写为保证构建的对象始终处于一致的状态。 它还避免了在构建对象的类中出现复杂的“伸缩构造函数”。 还有一个问题是,如果您希望构建的对象是不可变的(例如,为了线程安全),它就不能有 setter 方法。
Joshua Bloch in Effective Java Item #2 strongly recommends the use of a Builder when you have a constructor with a lot of arguments. One reason is that it can be written to guarantee that the built object is always in a consistent state. It also avoids having complex "telescoping constructors" in the built object's class. Still another is that if you want the built object to be immutable (eg, for thread safety), it can't have setter methods.