var java 10
¿Cuál es el equivalente de la palabra clave C#''var'' en Java? (15)
A partir de Java 10, el equivalente es ... var
.
Un uso de la palabra clave var en C # es la declaración de tipo implícita. ¿Cuál es la sintaxis equivalente de Java para var ?
Con el lanzamiento de JDK 10 el 20 de marzo, Java ahora incluye un nombre de tipo var
reservado (no una palabra clave, consulte a continuación) como se especifica en openjdk.java.net/jeps/286 . Para las variables locales, lo siguiente ahora es válido en Java 10 o superior:
var map = new HashMap<String, Integer>();
El nombre de tipo reservado var
en Java es casi idéntico a la palabra clave var
en C #, ya que ambos permiten la escritura implícita (consulte a continuación las diferencias importantes). var
en Java solo se puede usar para la inferencia de tipos implícita en los siguientes contextos (como se enumeran en JEP 286: Objetivos ):
- variables locales con inicializadores
- Índices en el bucle for mejorado
- locales declarados en un tradicional for-loop
Por lo tanto, var
no se puede utilizar para campos, tipos de retorno, nombres de clase o nombres de interfaz. Su justificación es eliminar la necesidad de incluir nombres de tipo largos al declarar y definir variables locales, como se indica en openjdk.java.net/jeps/286 (escrito por Brian Goetz):
Buscamos mejorar la experiencia del desarrollador al reducir la ceremonia asociada con la escritura de código Java, al tiempo que mantenemos el compromiso de Java con la seguridad de tipo estático, al permitir que los desarrolladores elijan la declaración manifiesta, a menudo innecesaria, de los tipos de variables locales.
var
Scoping en Java
Cabe señalar que var
no es una palabra clave en Java, sino un nombre de tipo reservado. Como se cita en 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 utiliza 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 dado que var
es un nombre de tipo reservado y no una palabra clave, aún puede usarse para nombres de paquetes, nombres de métodos y nombres de variables (junto con su nuevo rol de tipo de interferencia). Por ejemplo, los siguientes son 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 en JEP 286:
Este tratamiento se restringiría a variables locales con inicializadores, índices en el bucle for mejorado y locales declarados en un bucle for tradicional; no estaría disponible para métodos formales, formales de constructores, tipos de retorno de métodos, campos, formales 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 incluye lo siguiente: var
se puede usar como nombre de tipo en C #, pero no se puede usar como nombre de clase o interfaz en Java. De acuerdo con la documentación de C # (Variables locales implícitamente escritas) :
Si un tipo llamado
var
está en el alcance, entonces la palabra clavevar
se resolverá con ese nombre de tipo y no se tratará como parte de una declaración de variable local de tipo implícito.
La capacidad de usar var
como nombre de tipo en C # crea cierta complejidad e introduce algunas reglas de resolución complejas, que se evitan mediante var
en Java al deshabilitar var
como nombre de clase o interfaz. Para obtener información sobre las complejidades de los nombres de tipo var
en C #, consulte Restricciones que se aplican a las declaraciones de variables de tipo implícito . Para obtener más información sobre las razones detrás de la decisión de alcance para `var en Java, consulte JEP 286: Opciones de alcance .
En general, puede usar la clase Objeto para cualquier tipo, ¡pero tiene que realizar la conversión de tipos más adelante!
p.ej:-
Object object = 12;
Object object1 = "Aditya";
Object object2 = 12.12;
System.out.println(Integer.parseInt(object.toString()) + 2);
System.out.println(object1.toString() + " Kumar");
System.out.println(Double.parseDouble(object2.toString()) + 2.12);
Esta función ahora está disponible en Java SE 10. La var estática, segura para el tipo, finalmente ha logrado ingresar al mundo de Java :)
fuente: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
He preparado un plugin para IntelliJ que, de alguna manera, te da var
en Java. Es un truco, por lo que se aplican los descargos de responsabilidad habituales, pero si usa IntelliJ para su desarrollo Java y quiere probarlo, está en https://bitbucket.org/balpha/varsity .
JEP - JDK Enhancement-Proposal
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>
Java 10 obtuvo inferencia de tipo de variable local, por lo que ahora tiene una var
que es bastante equivalente a la C # one (que yo sepa).
También puede inferir tipos no denotables (tipos que el programador no pudo nombrar en ese lugar; aunque los tipos que no se pueden denotar son diferentes, por ejemplo, Java no tiene un equivalente a los tipos anónimos de C #).
La única diferencia que pude encontrar es que en C #,
En Java 10 var
no es un nombre de tipo legal.
No hay ninguno. Por desgracia, tienes que escribir el nombre completo del tipo.
Edición: 7 años después de la publicación, se agregó inferencia de tipo para variables locales (con var
) en Java 10.
Edición: 6 años después de haber sido publicado, para recopilar algunos de los comentarios a continuación:
La razón por la que C # tiene la palabra clave
var
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 hábiles). No sé si esto ha cambiado mientras tanto.var
no es lo mismo quedynamic
.var
variables todavía están tipificadas estáticamente al 100%. Esto no compilará:var myString = "foo"; myString = 3;
var
también es útil cuando el tipo es obvio desde el contexto. Por ejemplo:var currentUser = User.GetCurrent();
Puedo decir que en cualquier código del cual soy responsable,
currentUser
tiene unUser
o clase derivada. Obviamente, si su implementación deUser.GetCurrent
devuelve un int, entonces tal vez esto sea un detrimento para usted.Esto no tiene nada que ver con
var
, pero si tiene jerarquías de herencia extrañas donde se ocultan los 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 que se emiten como .No puedo imaginar un escenario real en el que esto sea indicativo de un buen diseño, pero puede 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 indica, los métodos virtuales no se ven afectados por esto.
No, no hay una manera no torpe de inicializar una
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, simplemente hazlo a la manera antigua:
object foo6;
Puede, en Java 10, pero solo para las variables locales , es decir,
Usted puede,
var anum = 10; var aString = "Var";
Pero no puedo
var anull = null; // Since the type can''t be inferred in this case
Echa un vistazo a la spec para más información.
Puedes echarle un vistazo a Kotlin de JetBrains, pero es valioso. no var.
Sé que es más antiguo, pero ¿por qué no crear una clase var y crear constructores con diferentes tipos y, dependiendo de qué invocadores se invocan, se obtiene var con un tipo diferente? Incluso podrías construir métodos para convertir un tipo a otro.
Se admitirá en JDK 10. Incluso es posible verlo en acción en la compilación de acceso temprano .
El openjdk.java.net/jeps/286 :
Mejore el lenguaje Java para extender la inferencia de tipos a las 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
es ahora un nombre de tipo reservado - ¡Java sigue comprometido con la escritura estática!
- Solo se puede utilizar en declaraciones de variables locales.
Si desea intentarlo sin instalar Java en su sistema local, creé una imagen de Docker con JDK 10 instalado:
$ docker run -it marounbassam/ubuntu-java10 bash
root@299d86f1c39a:/# 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 ==> []
Si agrega Lombok a su proyecto, puede usar su palabra clave val .
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 para usted.
De hecho, acabo de agregar una clase llamada ''var'', por lo que no tengo que escribir algo diferente.
El código sigue siendo demasiado detallado, pero al menos no tiene que escribirlo.
Lombok
soporta var pero todavía se clasifica como experimental:
import lombok.experimental.var;
var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);
Here hay un error que debe evitarse al intentar usarlo en IntelliJ IDEA
. Parece funcionar como se espera, aunque incluye la finalización automática y todo. Hasta que haya una solución "no hacky" (por ejemplo, debido a openjdk.java.net/jeps/286 ), esta podría ser su mejor apuesta en este momento.
Tenga en cuenta que val
es compatible con Lombok
sin modificar o crear un lombok.config
.