34

在 VB.NET 中有 WITH 命令可以让您省略对象名称而只访问所需的方法和属性。例如:

With foo
   .bar()
   .reset(true)
   myVar = .getName()
End With

Java中有这样的语法吗?

谢谢!

4

8 回答 8

33

不。当表达式过长时,您可以做的最好的事情是将其分配给具有短名称的局部变量,并用于{...}创建范围:

{
   TypeOfFoo it = foo; // foo could be any lengthy expression
   it.bar();
   it.reset(true);
   myvar = it.getName();
}
于 2009-09-29T20:40:31.467 回答
16

也许在 Java 中最接近的方法是在构造过程中使用双括号习惯用法。

Foo foo = new Foo() {{
    bar();
    reset(true);
    myVar = getName(); // Note though outer local variables must be final.
}};

或者,this可以链接返回的方法:

myName =
    foo
        .bar()
        .reset(true)
        .getName();

哪里barreset方法返回this

然而,想要这样做往往表明该对象没有足够丰富的行为。尝试重构到被调用的类。也许有不止一个班级试图出去。

于 2009-09-29T20:43:59.433 回答
15

使用 Java 8 lambda 可以非常接近,但缺点是无法修改局部变量。

声明这个方法:

static <T> void with(T obj, Consumer<T> c) {
    c.accept(obj);
}

所以你可以使用:

Window fooBarWindow = new Window(null);

String mcHammer = "Can't Touch This";

with(fooBarWindow, w -> {
     w.setAlwaysOnTop(true);
     w.setBackground(Color.yellow);
     w.setLocation(300, 300);

     w.setTitle(mcHammer); // can read local variables
     //mcHammer = "Stop!"; // won't compile - can't modify local variables
});

这也可以使用匿名类,但不那么干净。

于 2014-03-27T15:27:31.530 回答
6

一些对象允许您“链接”方法调用,这接近您喜欢的语法。例如,构建器类通常会从方法中返回自身,因此您可以执行以下操作:

MyObject b = new MyBuilder().setFoo(5).setBar(6).setBaz("garply!").build();

每个set...方法都会返回this,因此您可以链接下一次调用。

于 2009-09-29T20:44:32.350 回答
5

没有。Java 的策略是避免任何可能减少冗长的事情。

好吧,在写完这篇文章之后,我突然想到最接近的可能是静态导入,例如

package a.b.c.d;
public class Foo {
   public static void bar() {
      ...
   }
}

现在你可以做

package d.e.f;
import static a.b.c.d.Foo.*;

bar();
于 2009-09-29T20:39:54.667 回答
3

最接近这一点的是静态导入,它允许您调用静态方法,而无需显式指定方法所在的类。

于 2009-09-29T20:41:31.277 回答
2

如前所述,您不能真正用 Java 编写这样的代码。

就像注释一样,如果您害怕在需要更改变量名称的情况下进行多次复制/粘贴,Eclipse 允许您自动重命名变量的所有引用:

在“foo”变量名上使用ALT++ ,您可以一次重命名为“ SHIFTmyFoo R”,例如:

Foo myFoo = new Foo();
myFoo.bar();
myFoo.reset(true);
于 2014-05-21T14:11:12.247 回答
0

如果你有 Foo 的实现,你可以使用 fluent API 的概念。

可以说你有:

public class Foo {
    private String a;
    private String b;
    public void setA(String a) { this.a = a; }
    public void setB(String b) { this.b = b; }
    public String getName() { return this.a + " " + this.b; }
}

然后你可以修改它以获得这个:

public class Foo {
    private String a;
    private String b;
    public Foo setA(String a) { this.a = a; return this; }
    public Foo setB(String b) { this.b = b; return this; }
    public String getName() { return this.a + " " + this.b; }
}

您的调用代码可能如下所示:

String name = new Foo().setA("foo")
                       .setB("bar")
                       .getName();

享受!

于 2019-09-04T13:18:56.980 回答