虽然我在前面回答了一些问题,但最近我一直在做的一些工作中,我一直在想为什么Java不支持对其内置类进行方法链接。
例如,如果我要创建一个Car
类,我可以通过重新this
而不是void来使其可链接,如下所示:
public class Car {
private String make;
public Car setMake(String make) {
this.make = make;
return this;
}
}
为什么内置库不倾向于以这种方式做事有什么特别的原因?方法链是否存在缺点?
我可能忽略了一些可以解释缺少方法链接的东西,但是默认情况下返回void的任何setter方法都应该返回对 this 的引用(至少在我看来应该如此)。这将使以下情况变得更加清洁。
container.add((new JLabel("label text")).setMaximumSize(new Dimension(100,200)));
而不是更长的啰嗦:注意:如果你愿意,它不会阻止你以这种方式编码。
JLabel label = new JLabel("label text");
label.setMaximumSize(new Dimension(100,200));
container.add(label);
我很想知道这个决定背后的原因,如果我不得不猜测会有与此相关的开销,所以只应在需要时使用。
答案 0 :(得分:33)
的Eh。可以在两个方向上进行可读性论证 - 这样的事情就是试图将过多的东西放在一行中。
但老实说,我怀疑这是出于历史原因:普遍的“链接”行为并没有真正变得流行或众所周知,例如Swing正在开发中。您可能会争辩说它应该在以后添加,但是这样的事情往往会产生二进制不兼容性以及Sun / Oracle历来非常谨慎的其他问题。
更新的JDK库 - 请参阅例如ByteBuffer
对于一个主要的,众所周知的示例 - 提供了链接行为等,这是有意义的。
答案 1 :(得分:19)
我能想到的另一个原因是表现,或者更准确地说:不为你不能使用的东西买单。 return this
在每个方法之后都不是很昂贵,但仍然需要很少的额外CPU周期和一个CPU注册表。
甚至有一个想法是为每个声明return this
返回值的方法添加隐式void
,但它被拒绝了。
答案 2 :(得分:9)
虽然我们可以猜测真正的原因,但其中一个可能是严格来说,它不是非常OO。
如果您将方法视为表示建模世界的操作的操作,则方法链不适合该图片。
另一个原因可能是当您尝试覆盖链式方法时可能发生的混乱。想象一下这种情况:
class Foo {
Foo chainedMethod() {...}
}
class Bar extends Foo {
Foo chainedMethod() {...} //had to return Foo for Java versions < 1.5
void doStuff();
}
因此,当您尝试new Bar().chainedMethod().doStuff()
时,它将无法编译。 ((Bar)new Bar().chainedMethod()).doStuff()
看起来不太好,是吗:)。
答案 3 :(得分:4)
方法链通常与Builder模式一起使用,您可以在StringBuilder
类中看到它。除此之外,方法链接可以使命令和创建分离不那么清晰,例如repaint()
是否也应该是流畅界面的一部分?然后我可以:
container.add(label).repaint().setMaximumSize(new Dimension(100,200)));
突然,我的调用顺序变得很重要,可以隐藏在链接方法中。
答案 4 :(得分:1)
不实施方法链接的原因将是以下部分:
Method Chaining的最大问题是整理问题。 虽然有解决方法,但通常如果遇到这种情况你就是这样 最好使用嵌套函数。嵌套函数也更好 选择是否遇到了Context Variables。
无法保证链外的对象实际上会返回有效的对象, 非null对象。此外,调试这种代码风格通常很多 更难,因为许多* IDE *不会在调试时评估方法调用 时间作为你可以检查的对象
当你将例程调用到其他类时,它会让人感到困惑 当有很多时,将参数传递给其中一个链接方法 传递的参数主要是因为线条很长
还存在一个性能问题,它会对内存起作用
答案 5 :(得分:1)