简体   繁体   中英

WITH statement in Java

In VB.NET there is the WITH command that lets you omit an object name and only access the methods and properties needed. For example:

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

Is there any such syntax within Java?

Thanks!

No. The best you can do, when the expression is overly long, is to assign it to a local variable with a short name, and use {...} to create a scope:

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

Perhaps the closest way of doing that in Java is the double brace idiom, during construction.

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

Alternatively, methods that return this can be chained:

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

where bar and reset methods return this .

However, wanting to do this tends to indicate that the object does not have rich enough behaviour. Try refactoring into the called class. Perhaps there is more than one class trying to get out.

You can get quite close using Java 8 lambdas, with a drawback of not being able to modify local variables.

Declare this method:

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

So you can use:

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

This is also possible using an anonymous class, but not as clean.

Some objects allow you to "chain" method invocations, which approaches the syntax you like. For example, often a builder class will return itself from methods so you can do something like this:

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

Each set... method returns this so you can chain the next invocation.

Nope. Java has a policy of avoiding anything that might reduce verbosity.

Well, after writing this it just occurred to me that the closest thing might be static imports, eg

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

and now you can do

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

bar();

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

As already said, you cannot really write the code as this in Java.

Just as a comment, if you are affraid of many copy/paste in the case you need to change the variable name, Eclipse allows you to rename all the references of the variable automatically:

Using ALT + SHIFT + R on the "foo" variable name, you can rename all at once to "myFoo" for instance:

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

If you have hands on the implementation of Foo, you can use the fluent API concept.

Lets say you have that:

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

Then you could modify it to obtain this:

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

And your calling code could look like:

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

Enjoy!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM