Java中的方法链接

在回答前面几个问题的同时,从最近的一些工作中,我一直在想,为什么Java不支持内置类的方法链接。

例如,如果我要创build一个Car类,那么我可以通过重新构造它来链接 ,而不是void,如下所示:

 public class Car { private String make; public Car setMake(String make) { this.make = make; return this; } } 

为什么内build的图书馆不倾向于这样做? 方法链有缺点吗?

我可能忽略了一些可以解释缺less方法链接的东西,但是默认情况下返回void的任何setter方法都应该返回一个对此的引用(至less在我眼中应该是这样)。 这会使下面的情况更加清洁。

 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); 

我会很有兴趣听到这个决定背后的原因,如果我不得不猜测这将是一个相关的开销,所以应该只在需要时使用。

呃。 有两个方向的可读性论据 – 有这样一个事情,试图把太多的东西放在一个单一的线。

但说实话,我怀疑这是出于历史原因:当Swing被开发出来的时候,普遍的“链接”行为并没有真正stream行起来或者是众所周知的。 你可能会争辩说,它应该在以后被添加,但是这样的事情往往会造成二进制不兼容以及Sun / Oracle历来非常谨慎的其他问题。

最近的JDK库(见例如ByteBuffer作为一个主要的着名例子)提供了链接行为等等,在这里它是有道理的。

我能想到的另一个原因是性能 ,或者更确切地说:不支付你不使用的东西。 每个方法都不是很昂贵,但是仍然需要额外的CPU周期和一个CPUregistry。

甚至有一个想法,将隐式返回值添加到每个声明void返回值的方法,但是被拒绝了。

虽然我们可以猜出真正的原因,但其中一个严格来说可能不是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()看起来不太好,是不是:)

方法链通常与Builder模式一起使用,您可以在StringBuilder类中看到这一点。 除此之外,方法链可以使命令和创build分离不太清楚,例如repaint()也应该是stream畅接口的一部分吗? 那么我可以有:

 container.add(label).repaint().setMaximumSize(new Dimension(100,200))); 

突然间,我的呼叫顺序变得重要,可以隐藏在方法链中。

你真的在问德米特法

“只和你的直接朋友交谈”

请注意,上面的链接是一个很好的资源,但你可以花很长时间,没有得到你正在寻找的答案! 🙂

没有实现方法链接的原因是以下几点:

  • 方法链接最大的问题是完成问题。 虽然有解决方法,通常如果遇到这个问题,最好使用嵌套函数。 嵌套函数也是一个更好的select,如果你陷入了与上下文variables混乱。

  • 不能保证链外的对象实际上会返回一个有效的非空对象。 另外,debugging这种types的代码往往比较困难,因为很多* IDE在debugging时不会将方法调用作为一个可以检查的对象

  • 当你调用其他类的例程向其中一个链接方法传递参数时,可能会引起混淆,因为有很多参数要传递,主要是因为行变得很长

  • 还有一个性能问题,它将努力记忆