2009-09-29 84 views
27

En VB.NET existe el comando WITH que le permite omitir un nombre de objeto y acceder solo a los métodos y propiedades necesarios. Por ejemplo:instrucción WITH en Java

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

¿Existe tal sintaxis en Java?

Gracias!

+1

Gracias por todas las respuestas. Estaba bastante seguro de que no existía tal sintaxis. Un montón de buenas sugerencias para diversas situaciones. –

Respuesta

30

No. Lo mejor que puede hacer, cuando la expresión es demasiado largo, es asignar a una variable local con un nombre corto, y utilizar {...} crear un ámbito:

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

Mi comprensión de VB no es genial, pero no creo que lo esté haciendo. –

+0

(El equivalente de Java sería 'foo.bar(); foo.reset (true); String myVar = foo.getName();'.) –

+0

Sería, pero no tiene mucho sentido hacer esto en absoluto cuando ya tienes una variable como 'foo', por eso cambié el ejemplo para involucrar una expresión más complicada. En VB también, 'With' se usa más a menudo con expresiones largas. Además, no es necesario declarar 'myVar', presumiblemente ya está declarado en el ámbito externo. 'True' necesita corregirse, gracias por señalar eso. –

3

No. Java tiene una política de evitar todo lo que pueda reducir la verbosidad.

Bueno, después de escribir esto, se me acaba de ocurrir que lo más parecido podrían ser las importaciones estáticas, p.

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

y ahora se puede hacer

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

bar(); 
+0

Verbose? Supongo que se equivocaron cuando crearon el operador condicional (? :) entonces. VB tiende a ser mucho más detallado que Java. –

+0

"No, Java tiene una política de evitar todo lo que pueda reducir la verborrea". - Gracioso como en el humor de la horca. –

3

lo más parecido a esto es las importaciones estáticas que le permiten llamar a métodos estáticos sin especificar explícitamente la clase en la que existe el método.

15

Quizás la manera más cercana de hacer eso en Java es la expresión doble del paréntesis, durante la construcción.

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

Alternativamente, métodos que devuelven this pueden encadenarse:

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

donde bar y reset métodos devuelven this.

Sin embargo, querer hacer esto tiende a indicar que el objeto no tiene un comportamiento lo suficientemente rico. Intente refactorizar en la clase llamada. Tal vez hay más de una clase tratando de salir.

+6

No recomendaría la "expresión idiomática doble" sin señalar cómo funciona: no es simplemente azúcar sintáctica. Es una subclase anónima con un bloque de inicializador de instancia dentro de ella. Esto significa que cada uso de él hincha el código en el jar y en la memoria con una clase extra y significa que la clase en tiempo de ejecución del objeto creado es una subclase de la clase nombrada. – Boann

+2

Cualquiera que use ese primer "idioma" está sacrificando la legibilidad y el diseño para hacer algo más corto. Si la clase fue diseñada para encadenarse, entonces ciertamente puede usarse (pero no puedo restar importancia a esas respuestas por separado). –

6

Algunos objetos le permiten "invocar" las invocaciones de métodos, lo que se acerca a la sintaxis que desea. Por ejemplo, a menudo una clase constructor volverá en sí a partir de métodos para que pueda hacer algo como esto:

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

Cada método devuelve set...this por lo que puede encadenar la siguiente invocación.

8

Puede acercarse bastante utilizando Java 8 lambdas, con el inconveniente de no poder modificar las variables locales.

Declarar este método:

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

lo que puede utilizar:

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

Esto también es posible el uso de una clase anónima, pero no tan limpio.

+2

En los compiladores actuales y máquinas virtuales, esto cargará una clase anónima para el bloque e instanciará cada vez que se ejecute el bloque. Personalmente, me parece demasiado pesado, cuando la sugerencia de @PavelMinaev no requiere esto. Sin embargo, esta es una idea interesante e inteligente. – Boann

2

Como ya he dicho, realmente no se puede escribir el código como este en Java.

Así como un comentario, si participaban de muchos de copiar/pegar en el caso de tener que cambiar el nombre de la variable, Eclipse le permite cambiar el nombre de todas las referencias de la variable de forma automática:

Usando ALT + SHIFT + R en el "foo" nombre de la variable, puede cambiar el nombre de una sola vez a "myFoo", por ejemplo:

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