java Java中的方法链
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11561817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Method Chaining in Java
提问by Jon Taylor
While answering a few questions on here earlier and from some work I have been doing lately I have been wondering why Java does not support method chaining on its built in classes.
在之前在这里回答一些问题以及最近我一直在做的一些工作中,我一直想知道为什么 Java 不支持其内置类的方法链。
If I were to create a Car
class for example, I could make it chainableby reutrning this
instead of void as follows:
Car
例如,如果我要创建一个类,我可以通过 reutrning而不是 void使其可链接,this
如下所示:
public class Car {
private String make;
public Car setMake(String make) {
this.make = make;
return this;
}
}
Is there any particular reason why the built in libraries don't tend to do things this way? Is there a downside to method chaining?
内置库不倾向于以这种方式做事有什么特别的原因吗?方法链有缺点吗?
I may have overlooked something which would explain the lack of method chaining however any setter method that returns void by default should return a reference to this(at least in my eyes it should). This would make situations like the following much cleaner.
我可能忽略了一些可以解释缺少方法链的东西,但是默认情况下返回 void 的任何 setter 方法都应该返回对此的引用(至少在我看来应该如此)。这将使以下情况更加清晰。
container.add((new JLabel("label text")).setMaximumSize(new Dimension(100,200)));
rather than the more long winded: Note: It would not stop you from coding this way if you wished.
而不是更冗长:注意:如果您愿意,它不会阻止您以这种方式编码。
JLabel label = new JLabel("label text");
label.setMaximumSize(new Dimension(100,200));
container.add(label);
I would be very interested to hear the reasons behind this decision, If I had to guess it would be that there is an overhead associated with this and so should only be used when needed.
我很想知道这个决定背后的原因,如果我不得不猜测,这将是与此相关的开销,因此应该只在需要时使用。
采纳答案by Louis Wasserman
Eh. There's readability arguments to be made in both directions -- there's such a thing as trying to put too much into a single line.
诶。需要在两个方向上进行可读性论证——试图在一行中放入太多内容。
But honestly, I suspect here it's for historical reasons: pervasive "chaining" behavior hadn't really become popular or well-known when e.g. Swing was being developed. You could argue that it should've been added in later on, but things like that tend to create binary incompatibilities and other issues that Sun/Oracle have historically been extremely cautious about.
但老实说,我怀疑这是出于历史原因:普遍的“链接”行为在例如 Swing 被开发时并没有真正流行或广为人知。您可能会争辩说它应该在以后添加,但类似的事情往往会造成二进制不兼容和 Sun/Oracle 历来非常谨慎的其他问题。
More recent JDK libraries -- see e.g. ByteBuffer
for a major, well-known example -- haveprovided chaining behavior and the like, where it makes sense.
最近的JDK库-例如参见ByteBuffer
承重大,著名的例子-已提供链接行为等等,其中很有道理。
回答by Tomasz Nurkiewicz
Another reason I can think of is performance, or more precisely: don't pay for something you don't use. return this
after each and every method isn't very costly, but still requires few extra CPU cycles and one CPU registry.
我能想到的另一个原因是性能,或者更准确地说:不要为不使用的东西付费。return this
每一种方法都不是很昂贵,但仍然需要很少的额外 CPU 周期和一个 CPU 注册表。
There was even an idea to add implicit return this
to every method declaring void
return value but it was rejected.
甚至有一个想法为return this
每个声明void
返回值的方法添加隐式,但它被拒绝了。
回答by biziclop
Although we can but guess as to the real reason, one of them could be that strictly speaking it's not very OO.
虽然我们只能猜测真正的原因,但其中之一可能是严格来说它不是很OO。
If you view methods as actions that represent an action of the modelled world, method chaining doesn't really fit into that picture.
如果您将方法视为代表建模世界的动作的动作,则方法链并不真正适合该图。
Another reason could be the chaos that might ensue when you're trying to override a chained method. Imagine this situation:
另一个原因可能是当您尝试覆盖链接方法时可能会出现混乱。想象一下这种情况:
class Foo {
Foo chainedMethod() {...}
}
class Bar extends Foo {
Foo chainedMethod() {...} //had to return Foo for Java versions < 1.5
void doStuff();
}
So when you're trying to do new Bar().chainedMethod().doStuff()
, it won't compile. And ((Bar)new Bar().chainedMethod()).doStuff()
doesn't look very good, does it :)
所以当你试图做时new Bar().chainedMethod().doStuff()
,它不会编译。而且((Bar)new Bar().chainedMethod()).doStuff()
看起来不太好,是吗:)
回答by Garrett Hall
Method chaining is typically used with the Builder pattern, and you can see this in the StringBuilder
class. Outside of that, method chaining can make the command and creation separation less clear, for instance should repaint()
also be part of the fluent interface? Then I could have:
方法链通常与 Builder 模式一起使用,您可以在StringBuilder
类中看到这一点。除此之外,方法链可以使命令和创建分离不太清楚,例如repaint()
也应该是流畅接口的一部分?然后我可以:
container.add(label).repaint().setMaximumSize(new Dimension(100,200)));
and suddenly the order of my calls becomes important which can get hidden in the method chaining.
突然间,我的调用顺序变得很重要,这可能会隐藏在方法链中。
回答by GingerHead
The reason behind not implementing method chaining would be some of the following:
不实现方法链的原因有以下几点:
The biggest problem for Method Chaining is the finishing problem. While there are workarounds, usually if you run into this you're better off using a Nested Function. Nested Functions are also a better choice if you are getting into a mess with Context Variables.
There's no guarantee that an object out of the chain will actually return a valid, non-null object. Also, debugging this style of code is often a lot harder since many *IDE*s will not evaluate the method call at debug time as an object that you can inspect
It can get confusing when you're calling routines to other classes to pass arguments to one of the chaining methods, when there are a lot of parameters to pass mainly because the lines get very long
There is also a performance issue, which will work hard on memory
方法链的最大问题是整理问题。虽然有解决方法,但通常如果您遇到这种情况,最好使用嵌套函数。如果您对上下文变量感到困惑,嵌套函数也是更好的选择。
无法保证链外的对象实际上会返回有效的非空对象。此外,调试这种风格的代码通常要困难得多,因为许多 *IDE* 在调试时不会将方法调用评估为您可以检查的对象
当您将例程调用到其他类以将参数传递给链接方法之一时,当有很多参数要传递时,这可能会令人困惑,这主要是因为行变得很长
还有一个性能问题,会在内存上吃力
回答by Jool
You are really asking about the Law of Demeter
你真的是在问得墨忒耳定律
"Only talk to your immediate friends"
“只和你最直接的朋友交谈”
Note that the above link is a wonderful resource but you can spend a long time there and not get an answer you were looking for! :-)
请注意,上面的链接是一个很好的资源,但您可能会在那里呆很长时间而没有得到您想要的答案!:-)