Java中的WITH语句

Mik*_*ark 32 java vb.net syntax syntactic-sugar

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

With foo
   .bar()
   .reset(true)
   myVar = .getName()
End With
Run Code Online (Sandbox Code Playgroud)

Java中是否有这样的语法?

谢谢!

Pav*_*aev 31

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

{
   TypeOfFoo it = foo; // foo could be any lengthy expression
   it.bar();
   it.reset(true);
   myvar = it.getName();
}
Run Code Online (Sandbox Code Playgroud)

  • 我对VB的理解不是很好,但我不认为它是这样做的. (3认同)

Tom*_*ine 17

也许在Java中最接近的方法是在构造期间使用双支撑习语.

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

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

myName =
    foo
        .bar()
        .reset(true)
        .getName();
Run Code Online (Sandbox Code Playgroud)

哪里barreset方法返回this.

但是,想要这样做往往表明该对象没有足够丰富的行为.尝试重构到被调用的类.也许有不止一个班级试图离开.

  • 我不推荐"双支撑成语"而不指出它是如何工作的:它不仅仅是语法糖.它是一个匿名子类,里面有一个实例初始化块.这意味着每次使用它都会在jar中和内存中使用额外的类来填充代码,这意味着创建的对象的运行时类是命名类的子类. (8认同)
  • 任何使用第一个"成语"的人都牺牲了可读性和设计来做更短的事情.如果该类是为链接而设计的,那么当然可以使用(但我不能单独将这些答案下载). (2认同)

jpf*_*ire 14

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

声明此方法:

static <T> void with(T obj, Consumer<T> c) {
    c.accept(obj);
}
Run Code Online (Sandbox Code Playgroud)

所以你可以使用:

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
});
Run Code Online (Sandbox Code Playgroud)

这也可以使用匿名类,但不是很干净.

  • 在当前的编译器和VM上,这将为块加载一个匿名类,并在每次块运行时实例化它.就个人而言,当@ PavelMinaev的建议不需要这个时,我发现它太重了.这是一个有趣而聪明的想法. (3认同)

Ste*_*ker 6

某些对象允许您"链接"方法调用,这会接近您喜欢的语法.例如,通常构建器类将从方法返回自己,因此您可以执行以下操作:

MyObject b = new MyBuilder().setFoo(5).setBar(6).setBaz("garply!").build();
Run Code Online (Sandbox Code Playgroud)

每个set...方法都返回,this以便您可以链接下一个调用.


Ste*_* B. 5

不。Java 有避免任何可能减少冗长的内容的策略。

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

package a.b.c.d;
public class Foo {
   public static void bar() {
      ...
   }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以做

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

bar();
Run Code Online (Sandbox Code Playgroud)

  • “不。Java 的政策是避免任何可能减少冗长的内容。” - 就像绞刑架上的幽默一样有趣。 (2认同)
  • @niloderoock,除了这也是真的。谷歌“java样板战争” (2认同)