2009-09-29 1 views
27

В VB.NET есть команда WITH, которая позволяет вам опустить имя объекта и получать доступ только к тем методам и свойствам, которые необходимы. Например:Оператор WITH в Java

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

Есть ли такой синтаксис в Java?

Спасибо!

+1

Спасибо за все ответы. Я был уверен, что такого синтаксиса не было. Много замечательных предложений для различных ситуаций. –

ответ

30

No. Лучшее, что вы можете сделать, когда выражение является слишком длинным, чтобы назначить его в локальную переменную с коротким именем, и использовать {...} создать область:

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

Мое понимание VB не очень велико, но я не думаю, что это так. –

+0

(эквивалентной Java будет 'foo.bar(); foo.reset (true); String myVar = foo.getName();'.) –

+0

Это было бы, но это не имеет большого значения для этого когда у вас уже есть переменная типа 'foo', поэтому я изменил этот пример, чтобы включить более сложное выражение. В VB также чаще используется 'With' с длинными выражениями. Кроме того, нет необходимости объявлять 'myVar' - по-видимому, он уже объявлен во внешней области. «Правда» нуждается в исправлении, спасибо, что указали это. –

3

Nope. В 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(); 
+0

Verbose? Я думаю, они перепутались, когда создали условный оператор (? :). VB имеет тенденцию быть гораздо более многословным, чем Java. –

+0

«Нет. В Java есть политика избегать всего, что могло бы уменьшить многословие». - смешно, как в виселице юмора. –

3

самое близкое к этому является статическим импорт, который позволит вам вызывать статические методы без явного указания класса, в котором существует метод.

15

Возможно, самый близкий способ сделать это на 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(); 

где bar и reset методы возвращают this.

Однако, желание сделать это имеет тенденцию указывать на то, что объект не имеет достаточно насыщенного поведения. Попробуйте рефакторинг в вызываемый класс. Возможно, существует более одного класса, пытающегося выбраться.

+6

Я бы не рекомендовал «двойную фигуру» без указания того, как она работает: это не просто синтаксический сахар. Это анонимный подкласс с блоком инициализатора экземпляра внутри него. Это означает, что каждое его использование раздувает код в банке и в памяти с дополнительным классом и означает, что класс времени выполнения созданного объекта является подклассом именованного класса. – Boann

+2

Любой, кто использует эту первую «идиому», жертвует удобочитаемостью и дизайном, чтобы сделать что-то более короткое. Если класс был предназначен для цепочки, то это, безусловно, может быть использовано (но я не могу сгладить эти ответы отдельно). –

6

Некоторые объекты позволяют вам «цепочки» вызовов метода, которые подходят к синтаксису, который вам нравится. Например, часто класс строитель будет возвращать себя из методов, так что вы можете сделать что-то вроде этого:

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

Каждый set... метод возвращает this так что вы можете приковать следующий вызов.

8

Вы можете довольно близко использовать Java 8 lambdas, с недостатком неспособности изменять локальные переменные.

Declare этот метод:

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

Это также возможно, используя анонимный класс, но не как чистый.

+2

В отношении текущих компиляторов и виртуальных машин это загружает анонимный класс для блока и создает экземпляр каждого раза при запуске блока. Лично я считаю, что слишком тяжеловес, когда предложение Павла Минаева не требует этого. Это интересная и умная идея. – Boann

2

Как уже говорилось, вы действительно не можете написать код, как это на Java.

Подобно тому, как комментарий, если вы отступаете многих копировать/вставить в случае, если необходимо изменить имя переменной, Eclipse позволяет переименовать все ссылки на переменную автоматически:

Использование ALT + SHIFT + R на «Foo» имя переменной, вы можете переименовать все сразу «MYFOO», например:

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