Java中的方法链接

Java中的方法链接,java,methods,chaining,method-chaining,Java,Methods,Chaining,Method Chaining,在回答前面的一些问题以及我最近所做的一些工作时,我一直在想为什么Java不支持在其内置类上的方法链接 例如,如果我要创建一个Car类,我可以通过重新尝试this而不是void,使其成为可链接的,如下所示: public class Car { private String make; public Car setMake(String make) { this.make = make; return this; }

在回答前面的一些问题以及我最近所做的一些工作时,我一直在想为什么Java不支持在其内置类上的方法链接

例如,如果我要创建一个
Car
类,我可以通过重新尝试
this
而不是void,使其成为可链接的,如下所示:

public class Car {
    private String make;        

    public Car setMake(String make) {
        this.make = make;
        return this;
    }   
}
有什么特别的原因使内置库不倾向于这样做吗?方法链接有缺点吗

我可能忽略了一些可以解释缺少方法链接的东西,但是任何默认返回void的setter方法都应该返回对此的引用(至少在我看来应该是这样)。这将使下面这样的情况变得更干净

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

我很想听听这个决定背后的原因,如果我不得不猜测的话,这将是一个与此相关的开销,因此应该只在需要时使用。

虽然我们只能猜测真正的原因,但其中一个可能是严格地说,这不是很糟糕

如果将方法视为表示建模世界的动作的动作,则方法链接实际上并不适合这种情况

另一个原因可能是当您试图覆盖链式方法时可能会出现混乱。想象一下这种情况:

class Foo {
   Foo chainedMethod() {...}
}

class Bar extends Foo {
   Foo chainedMethod() {...} //had to return Foo for Java versions < 1.5
   void doStuff();
}
class-Foo{
Foo chainedMethod(){…}
}
类栏扩展了Foo{
Foo chainedMethod(){…}//必须为<1.5的Java版本返回Foo
void doStuff();
}

因此,当您尝试执行
newbar().chainedMethod().doStuff()
时,它不会编译。而
((Bar)new Bar().chainedMethod()).doStuff()看起来不太好,是吗:)

呃。在两个方向上都有可读性的论据——有一种情况是试图在一行中放太多东西

但老实说,我怀疑这是出于历史原因:普遍的“链接”行为在Swing开发时并没有真正流行或广为人知。您可能会争辩说它应该在以后添加,但类似的事情往往会造成二进制不兼容以及Sun/Oracle历来非常谨慎的其他问题


最近的JDK库(例如,参见一个主要的、众所周知的示例)提供了链接行为等有意义的功能。

我能想到的另一个原因是性能,或者更准确地说:不要为你不使用的东西付费
在每个方法之后返回此
,成本不是很高,但仍然需要很少的额外CPU周期和一个CPU注册表


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

方法链接通常与生成器模式一起使用,您可以在
StringBuilder
类中看到这一点。除此之外,方法链接会使命令和创建的分离变得不那么清晰,例如
repaint()
是否也应该是fluent接口的一部分?那么我可以:

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

突然之间,我调用的顺序变得很重要,这可能隐藏在方法链接中。

不实现方法链接的原因可能是以下几点:

  • 方法链接的最大问题是完成问题。 虽然有解决办法,但通常如果你遇到这种情况,你会 最好使用嵌套函数。嵌套函数也是一种更好的方法 如果您正陷入上下文变量的混乱,请选择

  • 不能保证链外的对象会返回有效的, 非空对象。此外,调试这种风格的代码通常需要很多时间 更难的是,许多*IDE*在调试时都不会对方法调用求值 时间是你可以观察的对象

  • 当您向其他类调用例程以 当存在大量参数时,将参数传递给其中一个链接方法 要传递的参数的数量,主要是因为线变得很长

  • 还有一个性能问题,这会对内存造成很大影响


你真的在问 “只与你的直系朋友交谈”


请注意,上面的链接是一个很好的资源,但您可能会在那里花费很长时间,而得不到您想要的答案!:-)

我不确定我是否同意,我会说你只是一次执行多个动作。@JonTaylor,但为什么在建模的世界中,一个方法会返回一个值,而这个值没有发生?我知道你来自哪里,但我认为这就像要求一个启用奶酪和番茄酱的汉堡,而不是启用奶酪的汉堡,同样的汉堡又添加番茄酱启用。是的,我的例子很傻,但我想表达了我的观点(可能)。@JonTaylor面向对象的解决方案是将
setCheeseAndKetchup()操作结合起来。我不得不说,我不一定同意这个观点,但强硬的OO是基于严格模拟现实生活活动的方法原则。我也不是说我同意它。我更喜欢实际的解决方案,每一个告诉你必须做什么和不应该做什么的理论都可以延伸到实际可用的地方。对OO的过于严格的解释可能是一个真正的痛苦,但是尝试用方法链接来做任何事情而没有一点常识也可能是同样痛苦的。是的,这是一个可读性问题。是的,很遗憾他们没有更新swing,但是swing一直是我最不喜欢的Java方面之一。我相信这是正确的答案。作为一个历史记录,很多Java的创始人都有Smalltalk的背景。Smalltalk没有太多的“然后返回这个”方法,因为它有一个半圆形的方法链接语法结构