Java中的WITH语句

Java中的WITH语句,java,vb.net,syntax,syntactic-sugar,Java,Vb.net,Syntax,Syntactic Sugar,在VB.NET中,使用WITH命令可以省略对象名称,而只访问所需的方法和属性。例如: With foo .bar() .reset(true) myVar = .getName() End With Java中有这样的语法吗 谢谢 没有。Java有一个避免任何可能减少冗长的事情的策略 写了这篇文章后,我突然想到最接近的可能是静态导入,例如 package a.b.c.d; public class Foo { public static void bar() {

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

With foo
   .bar()
   .reset(true)
   myVar = .getName()
End With
Java中有这样的语法吗


谢谢

没有。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();

不可以。当表达式过长时,最好将其分配给一个名称较短的局部变量,然后使用
{…}
创建一个作用域:

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

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

在Java中,最接近的方法可能是在构造过程中使用双括号习惯用法

Foo foo = new Foo() {{
    bar();
    reset(true);
    myVar = getName(); // Note though outer local variables must be final.
}};
或者,可以链接返回此的方法:

myName =
    foo
        .bar()
        .reset(true)
        .getName();
其中
重置
方法返回

然而,想要这样做往往表明对象没有足够丰富的行为。尝试重构到被调用的类中。可能不止一个类试图退出。

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

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

每个
set…
方法都会返回
这个
,这样您就可以链接下一个调用。

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

声明此方法:

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

使用匿名类也可以做到这一点,但不尽可能干净。

如前所述,您无法在Java中编写这样的代码

作为注释,如果您在需要更改变量名的情况下遇到许多复制/粘贴问题,Eclipse允许您自动重命名变量的所有引用:

在“foo”变量名上使用ALT+SHIFT+R,可以一次将所有变量重命名为“myFoo”,例如:

Foo myFoo = new Foo();
myFoo.bar();
myFoo.reset(true);

如果您掌握了Foo的实现,那么可以使用fluentapi概念

假设你有:

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

享受吧

我对VB的理解不是很好,但我不认为它能做到这一点。(等效的Java应该是
foo.bar();foo.reset(true);String myVar=foo.getName();
)它会的,但是当你已经有了一个变量,比如
foo
,那么做就没有多大意义了,这就是为什么我把这个例子改成了一个更复杂的表达式。在VB中,
With
更常用于长表达式。而且,不需要声明
myVar
——可能它已经在外部范围中声明了<代码>正确需要更正,感谢您指出这一点。感谢所有回复。我很确定没有这样的语法。对于各种情况有很多很好的建议。冗长?我猜他们在创建条件运算符(?:)时搞砸了。VB往往比Java冗长得多。“不,Java有一个避免任何可能减少冗长的事情的策略。”-就像绞刑架上的幽默一样有趣。@Niloderook,除了它也是真的之外。谷歌“java样板战”我不会推荐“双括号习惯用法”,除非指出它是如何工作的:它不仅仅是语法上的糖分。它是一个匿名子类,内部有一个实例初始值设定项块。这意味着每次使用它都会在jar和内存中增加一个额外的类,这意味着创建的对象的运行时类是命名类的一个子类。任何使用第一个“习惯用法”的人都在牺牲可读性和设计来做一些更短的事情。如果该类是为链接而设计的,那么它当然可以使用(但我不能单独否决这些答案)。@Tom,
with
与任何
obj
一起工作,而不仅仅是
new
对象。{{}解决方案是解决内存泄漏的快速方法,在当前的编译器和VM上,这将为块加载一个匿名类,并在每次块运行时实例化它。就我个人而言,当@PavelMinaev的建议不需要这一点时,我觉得这太重了。这是一个有趣而聪明的想法。@Boann,lambdas自Java8以来非常常见。考虑到它们总是基于匿名类,我认为这种实例化已经过优化,不再是问题了,现在我们有多核CPU、千兆内存和云,所以除非你是为小型嵌入式设备或类似设备开发,谁会关心更多的KBs(甚至MBs)呢当然,Pavel的解决方案更简洁。这个解决方案是最好的,因为如果你返回T而不是void,你可以在树状结构中使用它,类似于Gradle或Groovy构建器,代码没有变化。而在最近的JVM版本中,性能通常不是问题。即使是(可能在Android上),您所需要的只是针对仅速度热点进行优化。对于大多数代码来说,性能是最重要的。
String name = new Foo().setA("foo")
                       .setB("bar")
                       .getName();