¿Cuál es el equivalente de la palabra clave ‘var’ de C# en Java?

13 minutos de lectura

avatar de usuario
Arturo

Un uso de la variable La palabra clave en C# es una declaración de tipo implícita. ¿Cuál es la sintaxis equivalente de Java para variable?

  • val (o var) si usa un idioma particular de “reemplazo de Java” 😉

    usuario166390

    14 de diciembre de 2010 a las 19:27

  • @pst: ¿eso sería Scala? Hm sí, lo es.

    – rsanna

    14 de diciembre de 2010 a las 21:20

  • Para IntelliJ, envié esto como una solicitud de función: youtrack.jetbrains.com/issue/IDEA-102808 El IDE podría colapsar el código para mostrar val o var aunque el código subyacente no lo tenga.

    – Jon Onstott

    10 de marzo de 2013 a las 19:26

  • @Jon He pirateado algo juntos para IntelliJ, mira mi respuesta.

    – balfa

    14/04/2013 a las 18:10

  • Ahora hay una propuesta para que esta función se incluya en Java: openjdk.java.net/jeps/286

    – McGin

    13 de marzo de 2016 a las 10:02

avatar de usuario
mike caron

No hay ninguno. Por desgracia, debe escribir el nombre completo del tipo.

Editar: 7 años después de su publicación, escriba inferencia para variables locales (con var) se agregó en Java 10.

Editar: 6 años después de su publicación, para recopilar algunos de los comentarios a continuación:

  • La razón por la que C# tiene la var La palabra clave es porque es posible tener Tipos que no tienen nombre en .NET. P.ej:

    var myData = new { a = 1, b = "2" };
    

    En este caso, sería imposible dar un tipo adecuado a myData. Hace 6 años, esto era imposible en Java (todos los tipos tenían nombres, incluso si eran extremadamente detallados y poco prácticos). No sé si esto ha cambiado mientras tanto.

  • var no es lo mismo que dynamic. varLos inables todavía están 100% tipificados estáticamente. Esto no compilará:

    var myString = "foo";
    myString = 3;
    
  • var también es útil cuando el tipo es obvio por el contexto. Por ejemplo:

    var currentUser = User.GetCurrent();
    

    Puedo decir que en cualquier código del que soy responsable, currentUser tiene un User o clase derivada en él. Obviamente, si su implementación de User.GetCurrent devuelve un int, entonces tal vez esto sea un detrimento para ti.

  • Esto no tiene nada que ver con varpero si tiene jerarquías de herencia extrañas en las que sombrea métodos con otros métodos (por ejemplo, new public void DoAThing()), no olvide que los métodos no virtuales se ven afectados por el Tipo al que se asignan.

    No puedo imaginar un escenario del mundo real en el que esto sea indicativo de un buen diseño, pero es posible que no funcione como espera:

    class Foo {
        public void Non() {}
        public virtual void Virt() {}
    }
    
    class Bar : Foo {
        public new void Non() {}
        public override void Virt() {}
    }
    
    class Baz {
        public static Foo GetFoo() {
            return new Bar();
        }
    }
    
    var foo = Baz.GetFoo();
    foo.Non();  // <- Foo.Non, not Bar.Non
    foo.Virt(); // <- Bar.Virt
    
    var bar = (Bar)foo;
    bar.Non();  // <- Bar.Non, not Foo.Non
    bar.Virt(); // <- Still Bar.Virt
    

    Como se indicó, los métodos virtuales no se ven afectados por esto.

  • No, no existe una forma sencilla de inicializar un var sin una variable real.

    var foo1 = "bar";        //good
    var foo2;                //bad, what type?
    var foo3 = null;         //bad, null doesn't have a type
    var foo4 = default(var); //what?
    var foo5 = (object)null; //legal, but go home, you're drunk
    

    En este caso, hazlo a la antigua usanza:

    object foo6;
    

  • @Mike Caron: C# tiene [default] Las llamadas no virtuales y los operadores no son virtuales, así que… var p = new X(); p.Z() no es lo mismo que SuperX p = new X(); p.Z() para todos los X y SuperX, aunque X : SuperX. Con var la estático tipo de p es siempre X en el primer ejemplo anterior, pero siempre SuperX en el segundo ejemplo. Una diferencia sutil pero importante a tener en cuenta. Pero tu respuesta es muy correcta 🙂

    usuario166390

    15 de diciembre de 2010 a las 20:10


  • @Jon Hanna: var no hace que el código sea menos claro. Más bien lo contrario en mi opinión. ¿Por qué, por ejemplo, escribir el tipo dos (o incluso tres) veces en la misma fila cuando lo declara y lo instancia (RadioButton radioButton = new RadioButton();)? var te hace pensar dos veces cuando nombras tus variables porque se enfoca en la funcionalidad en lugar del tipo (por ejemplo UserCollection collection = new userRepository.GetUsers(); algo más natural se convierte en var users = userRepository.GetUsers();). Si piensas var No está claro que sea solo porque no está acostumbrado.

    – Martín Odhelius

    6 de julio de 2012 a las 10:19

  • @MartinOdhelius var definitivamente puede hacer que el código sea claro cuando se usa bien, pero también puede hacer que no quede claro si se usa mal; como muchas opciones de formato. El equilibrio difiere dependiendo de cuánto use objetos anónimos y genéricos, ninguno de los cuales existía en .NET 1.0, lo que lo hace menos útil como palabra clave hipotética en la primera versión de C♯. Solo nombraría un RadioButton radioButton en el caso de un método de fábrica o de ayuda donde lo único significativo del botón era que era un RadioButtonde lo contrario eso es una locura con o sin var.

    – Jon Hanna

    6 de julio de 2012 a las 10:32

  • @Jon Hanna: Una vez fui tan crítico con var como tú, si no más, pero he cambiado de opinión, y quizás es tan simple como una cuestión de opiniones diferentes, porque sigo pensando que te equivocas cuando dices que es una cuestión de cuánto estás usando objetos anónimos y genéricos. 😉 La declaración de tipo suele ser solo ruido de código, si no puede entender el código sin él, es probable que el código no sea claro en cualquier caso.

    – Martín Odhelius

    6 de julio de 2012 a las 11:51

  • estas confundido variable con tipos anónimos. var en sí mismo simplemente le pide al compilador que deduzca el tipo de la asignación; es azúcar sintáctico. Al principio era escéptico al respecto, pero lo uso religiosamente y todavía tengo que encontrar un momento en el que haya causado confusión. Elimina la redundancia al crear instancias y elimina la necesidad de verificar el tipo al hacer referencia. No hay un equivalente de JAVA a partir de JAVA 9.

    – robar

    23 de enero de 2018 a las 19:51

avatar de usuario
darthtreviño

Si agrega Lombok a su proyecto, puede usar su valor palabra clave.

http://proyectolombok.org/features/val.html

  • @rightfold: Objetos cuya referencia es final no son necesariamente inmutables. Considerar final StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");

    – Matías Braun

    24 de marzo de 2014 a las 16:52

  • Desde lombok v1.16.12 también hay soporte experimental para var. proyectolombok.org/features/experimental/var.html

    -Roel Spilker

    29 de mayo de 2017 a las 18:26

  • @MatthiasBraun tu ejemplo es incorrecto. En este caso, la clase StringBuilder en sí misma es inmutable, solo agrega un valor de cadena a su estructura interna usando el método, esto es totalmente legal.

    –Andzej Maciusovic

    11 de agosto de 2017 a las 11:04

JEP – Propuesta de mejora de JDK

http://openjdk.java.net/jeps/286

JEP 286: Inferencia de tipo de variable local

Autor Brian Goetz

// Goals:
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

  • ¿Qué versión de Java? 10?

    -Peter Mortensen

    7 febrero 2018 a las 18:14

  • @PeterMortensen Sí. JEP 286 ha sido aceptado y publicado en JDK 10 (ver 286 en Características en openjdk.java.net/projects/jdk/10).

    – Justin Albano

    1 de abril de 2018 a las 12:42

avatar de usuario
justin albano

Con el lanzamiento de JDK 10 el 20 de marzo, Java ahora incluye un var nombre de tipo reservado (no una palabra clave; consulte a continuación) como se especifica en JPY 286. Para las variables locales, lo siguiente ahora es válido en Java 10 o superior:

var map = new HashMap<String, Integer>();

los var El nombre de tipo reservado en Java es casi idéntico al var palabra clave en C# en el sentido de que ambos permiten la escritura implícita (consulte las diferencias importantes a continuación). var en Java solo se puede usar para la inferencia de tipos implícitos en los siguientes contextos (como se enumera en JEP 286: Metas):

  • variables locales con inicializadores
  • índices en el bucle for mejorado
  • locales declarados en un bucle for tradicional

Por lo tanto var no poder utilizarse para campos, tipos de devolución, nombres de clase o nombres de interfaz. Su razón es eliminar la necesidad de incluir nombres de tipos largos al declarar y definir variables locales, como se indica en JPY 286 (escrito por Brian Goetz):

Buscamos mejorar la experiencia del desarrollador al reducir la ceremonia asociada con la escritura de código Java, mientras mantenemos el compromiso de Java con la seguridad de tipos estáticos, permitiendo a los desarrolladores eludir la declaración de manifiesto de tipos de variables locales, a menudo innecesaria.

var Alcance en Java

se debe notar que var no es una palabra clave en Java, sino un nombre de tipo reservado. Como se cita de JEP 286:

El identificador var no es una palabra clave; en su lugar, es un nombre de tipo reservado. Esto significa que el código que usa var como variable, método o nombre de paquete no se verá afectado; el código que usa var como clase o nombre de interfaz se verá afectado (pero estos nombres son raros en la práctica, ya que violan las convenciones de nomenclatura habituales).

Tenga en cuenta que desde var es un nombre de tipo reservado y no una palabra clave, aún se puede usar para nombres de paquetes, nombres de métodos y nombres de variables (junto con su nuevo rol de interferencia de tipos). Por ejemplo, los siguientes son todos ejemplos de usos válidos de var en Java:

var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;

Como se cita de JEP 286:

Este tratamiento estaría restringido a variables locales con inicializadores, índices en el bucle for mejorado y variables locales declaradas en un bucle for tradicional; no estaría disponible para formularios de método, formularios de constructor, tipos de devolución de método, campos, formularios de captura o cualquier otro tipo de declaración de variable.

Diferencias entre var en Java y C

Esta es una diferencia notable entre var en C# y Java incluyen lo siguiente: var se puede usar como nombre de tipo en C# pero no se puede usar como nombre de clase o nombre de interfaz en Java. De acuerdo con la Documentación de C# (Variables locales tipificadas implícitamente):

Si un tipo llamado var está dentro del alcance, entonces el var La palabra clave se resolverá en ese nombre de tipo y no se tratará como parte de una declaración de variable local tipificada implícitamente.

La habilidad de usar var como un nombre de tipo en C# crea cierta complejidad e introduce algunas reglas de resolución complejas, que se evitan mediante var en Java al no permitir var como un nombre de clase o interfaz. Para obtener información sobre las complejidades de var escriba nombres en C#, consulte Se aplican restricciones a las declaraciones de variables con tipos implícitos. Para obtener más información sobre el fundamento de la decisión de alcance de `var en Java, consulte JEP 286: Opciones de alcance.

Preparé un complemento para IntelliJ que, en cierto modo, le brinda var en Java. Es un truco, por lo que se aplican los descargos de responsabilidad habituales, pero si usa IntelliJ para su desarrollo de Java y quiere probarlo, está en https://bitbucket.org/balpha/varsity.

  • Sería genial tener un atajo de teclado para plegar/desplegar tipos de declaración en el editor actual. Gran complemento sin embargo.

    – tecla de acceso rápido

    17/08/2015 a las 14:50

  • @hotkey Esto utiliza el plegado de código incorporado de IntelliJ, por lo que puede desplegar todo con Ctrl-Shift-NumPadPlus. Cuando el cursor está en una línea que contiene una declaración de variable plegada, puede Ctrl-NumPadPlus y Ctrl-NumPadMinus para plegar/desplegar las declaraciones en el método actual. Doblar todas las declaraciones es un poco incómodo, tiene que doblar todo (Ctrl-Shift-NumPadMinus) y luego desplegar todo nuevamente (Ctrl-Shift-NumPadPlus).

    – balfa

    17 de agosto de 2015 a las 14:57

Será compatible con JDK 10. Incluso es posible verlo en acción en el compilación de acceso temprano.

los JPY 286:

Mejore el lenguaje Java para extender la inferencia de tipos a declaraciones de variables locales con inicializadores.

Así que ahora en lugar de escribir:

List<> list = new ArrayList<String>();
Stream<> stream = myStream();

Usted escribe:

var list = new ArrayList<String>();
var stream = myStream();

Notas:

  • var ahora es un nombre de tipo reservado
  • Java es todavía compromiso con la escritura estática!
  • Solo se puede usar en local declaraciones de variables

Si quiere probarlo sin instalar Java en su sistema local, creé un imagen acoplable con JDK 10 instalado en él:

$ docker run -it marounbassam/ubuntu-java10 bash
[email protected]:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
|  Welcome to JShell -- Version 10
|  For an introduction type: /help intro

jshell> var list = new ArrayList<String>();
list ==> []

  • Sería genial tener un atajo de teclado para plegar/desplegar tipos de declaraciones en el editor actual. Gran complemento sin embargo.

    – tecla de acceso directo

    17/08/2015 a las 14:50

  • @hotkey Esto utiliza el plegado de código incorporado de IntelliJ, por lo que puede desplegar todo con Ctrl-Shift-NumPadPlus. Cuando el cursor está en una línea que contiene una declaración de variable plegada, puede Ctrl-NumPadPlus y Ctrl-NumPadMinus para plegar/desplegar las declaraciones en el método actual. Doblar todas las declaraciones es un poco incómodo, tiene que doblar todo (Ctrl-Shift-NumPadMinus) y luego desplegar todo nuevamente (Ctrl-Shift-NumPadPlus).

    – balfa

    17 de agosto de 2015 a las 14:57

avatar de usuario
Pedro Mortensen

Una solución simple (suponiendo que esté utilizando un IDE decente) es simplemente escribir ‘int’ en todas partes y luego hacer que establezca el tipo por usted.

De hecho, acabo de agregar una clase llamada ‘var’ para no tener que escribir algo diferente.

El código sigue siendo demasiado detallado, ¡pero al menos no tienes que escribirlo!

  • Cuando dice “IDE decente”, ¿se excluye Eclipse*? — esto no parece funcionar en Luna (al menos cuando lo probé con int) — ¿Me estoy perdiendo de algo? (*: aunque nunca llamaría a Eclipse un IDE decente, no puedo juzgar por los demás…)

    – BrainSlugs83

    23 de septiembre de 2014 a las 5:00

  • @ BrainSlugs83 no sé, estoy usando IDEA, realmente no usé eclipse antes. ¿No te corrige los tipos? Estoy acostumbrado a c#/visual studio/resharper, que es como IDEA, ¡excepto que en realidad funciona correctamente! En todos los jetbrains, puede presionar alt-enter para obtener una lista de sugerencias cuando hay un error, por lo que establecer el tipo en int introduce un error en el que puede alt-enter y obtenerlo para ordenar el tipo

    – Jonny Raa

    23 de septiembre de 2014 a las 8:05

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad