Um uso da palavra-chave var em C # é uma declaração implícita de tipo. Qual é a sintaxe equivalente a Java para var ?
Um uso da palavra-chave var em C # é uma declaração implícita de tipo. Qual é a sintaxe equivalente a Java para var ?
Respostas:
Não há nenhum. Infelizmente, você precisa digitar o nome completo do tipo.
Edit: 7 anos após o lançamento, a inferência de tipo para variáveis locais (com var
) foi adicionada no Java 10.
Editar: 6 anos após a publicação, para coletar alguns dos comentários abaixo:
O motivo pelo qual C # tem a var
palavra-chave é que é possível ter tipos que não têm nome no .NET. Por exemplo:
var myData = new { a = 1, b = "2" };
Nesse caso, seria impossível atribuir um tipo adequado myData
. Há 6 anos, isso era impossível em Java (todos os tipos tinham nomes, mesmo que fossem extremamente detalhados e pouco controlados). Não sei se isso mudou nesse meio tempo.
var
não é o mesmo que dynamic
. var
Os dados ainda são 100% digitados estaticamente. Isso não será compilado:
var myString = "foo";
myString = 3;
var
também é útil quando o tipo é óbvio no contexto. Por exemplo:
var currentUser = User.GetCurrent();
Posso dizer que em qualquer código pelo qual sou responsável, currentUser
há uma User
classe ou classe derivada. Obviamente, se sua implementação de User.GetCurrent
retornar um int, talvez isso seja um prejuízo para você.
Isso não tem nada a ver com isso var
, mas se você tiver hierarquias de herança estranhas nas quais sombreia métodos com outros métodos (por exemplo new public void DoAThing()
), não esqueça que métodos não virtuais são afetados pelo tipo em que são convertidos.
Não consigo imaginar um cenário do mundo real em que isso seja indicativo de bom design, mas isso pode não funcionar como o esperado:
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 indicado, os métodos virtuais não são afetados por isso.
Não, não há uma maneira não desajeitada de inicializar a var
sem uma variável 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
Nesse caso, faça da maneira antiga:
object foo6;
var p = new X(); p.Z()
não é o mesmo que SuperX p = new X(); p.Z()
para todos os X e SuperX, apesar de tudo X : SuperX
. Com var
o tipo estático,p
está sempre X
no primeiro exemplo acima, mas sempre SuperX
no segundo exemplo. Uma diferença sutil, mas importante, para estar ciente. Mas a sua resposta está muito correta :-) #
var
não torna o código menos claro. Pelo contrário, na minha opinião. Por que, por exemplo, escreva o tipo duas (ou até três) vezes na mesma linha quando você a declara e a instancia ( RadioButton radioButton = new RadioButton();
)? var
faz com que você pense duas vezes ao nomear suas variáveis, porque ele se concentra mais na funcionalidade do que no tipo (por exemplo, UserCollection collection = new userRepository.GetUsers();
mais naturalmente se transforma var users = userRepository.GetUsers();
). Se você acha que var
não está claro, é porque não está acostumado.
var
pode deixar bem claro o código usado, mas também pode deixar claro o mau uso; como muitas opções de formatação. O saldo varia de acordo com o quanto você usa objetos e genéricos anônimos, nenhum dos quais existia no .NET 1.0, tornando-o menos útil como uma palavra-chave hipotética na primeira versão do C♯. Eu nomearia apenas a RadioButton
radioButton
no caso de um método de fábrica ou auxiliar, onde a única coisa significativa sobre o botão era que era um RadioButton
, caso contrário, isso é loucura com ou sem var
.
var
quanto você, se não mais, mas mudei de opinião, e talvez seja tão simples quanto uma questão de opiniões diferentes, porque ainda acho que você está errado quando diz que é um não importa o quanto você esteja usando objetos e genéricos anônimos;) A declaração de tipo geralmente é apenas um ruído de código; se você não conseguir entender o código sem ele, o código provavelmente não será claro nos dois casos.
var
ele próprio simplesmente pede ao compilador para inferir o tipo da atribuição; é açúcar sintático. Eu era cético a princípio, mas o uso religiosamente e ainda tenho que encontrar um momento em que isso causou confusão. Remove a redundância ao instanciar e remove a necessidade de verificar o tipo ao fazer referência. Não há equivalente JAVA como de JAVA 9.
Se você adicionar o Lombok ao seu projeto, poderá usar a palavra-chave val .
final
não são necessariamente imutáveis. Considerefinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.html
JEP - Proposta de aprimoramento do JDK
http://openjdk.java.net/jeps/286
JEP 286: Inferência de tipo variável local
Autor Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Eu criei um plugin para o IntelliJ que, de certa forma, fornece a você var
em Java. É um hack, então as isenções de responsabilidade usuais se aplicam, mas se você usa o IntelliJ para o seu desenvolvimento Java e deseja experimentá-lo, é em https://bitbucket.org/balpha/varsity .
Com o lançamento do JDK 10 em 20 de março, o Java agora inclui um var
nome de tipo reservado (não uma palavra-chave - veja abaixo), conforme especificado no JEP 286 . Para variáveis locais, o seguinte agora é válido no Java 10 ou superior:
var map = new HashMap<String, Integer>();
O var
nome do tipo reservado em Java é quase idêntico à var
palavra - chave em C #, pois ambos permitem digitação implícita (veja abaixo diferenças importantes). var
em Java pode ser usado apenas para inferência implícita de tipo nos seguintes contextos (conforme enumerado no JEP 286: Objetivos ):
Portanto, var
não pode ser usado para campos, tipos de retorno, nomes de classe ou nomes de interface. Sua lógica é remover a necessidade de incluir nomes de tipo longos ao declarar e definir variáveis locais, conforme declarado no JEP 286 (de autoria de Brian Goetz):
Procuramos melhorar a experiência do desenvolvedor, reduzindo a cerimônia associada à escrita do código Java, mantendo o compromisso do Java com a segurança de tipo estático, permitindo que os desenvolvedores excluam a declaração manifesta muitas vezes desnecessária dos tipos de variáveis locais.
var
Escopo em JavaNote-se que var
não é uma palavra-chave em Java, mas um nome de tipo reservado. Conforme citado no JEP 286:
O identificador var não é uma palavra-chave; em vez disso, é um nome de tipo reservado. Isso significa que o código que usa var como uma variável, método ou nome do pacote não será afetado; o código que usa var como nome de classe ou interface será afetado (mas na prática esses nomes são raros, pois violam as convenções de nomenclatura comuns).
Observe que, como var
é um nome de tipo reservado e não uma palavra-chave, ele ainda pode ser usado para nomes de pacotes, nomes de métodos e nomes de variáveis (junto com sua nova função de interferência de tipo). Por exemplo, todos os exemplos a seguir são de usos válidos var
em Java:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Conforme citado no JEP 286:
Esse tratamento seria restrito a variáveis locais com inicializadores, índices no loop for aprimorado e locais declarados em um loop for tradicional; não estaria disponível para formals de método, formals de construtor, tipos de retorno de método, campos, formals de captura ou qualquer outro tipo de declaração de variável.
var
em Java e CEssa é uma diferença notável entre var
C # e Java: o var
pode ser usado como um nome de tipo em C #, mas não pode ser usado como um nome de classe ou de interface em Java. De acordo com a documentação do C # (variáveis locais implicitamente digitadas) :
Se um tipo nomeado
var
estiver no escopo, avar
palavra - chave será resolvida com esse nome de tipo e não será tratada como parte de uma declaração de variável local digitada implicitamente.
A capacidade de usar var
como um nome de tipo em C # cria alguma complexidade e introduz algumas regras complexas de resolução, que são evitadas var
no Java ao proibir var
como nome de classe ou interface. Para obter informações sobre as complexidades dos var
nomes de tipos em C #, consulte Restrições se aplicam a declarações de variáveis de tipo implícito . Para obter mais informações sobre a lógica por trás da decisão de escopo para `var em Java, consulte JEP 286: Opções de Escopo .
var
campos ou tipos de retorno? Por que é importante notar?
var
em Java não pode ser usado para campos ou tipos de retorno. Isso é importante porque essa restrição torna var
sensível ao contexto, onde só pode ser usada em alguns contextos (variáveis locais) e não em outros. Essa não é necessariamente uma diferença entre Java e C # que deve ser observada, mas uma restrição importante em geral quando usada var
em Java.
var
um nome de classe e usá-lo como tal. Tecnicamente, é uma "palavra-chave de contexto" no caso de c #, mas em Java parece que você não pode fazer o mesmo. Corrija-me se eu estiver errado.
var
como um nome de classe ou um nome de interface em Java (o que não é comum de qualquer maneira), mas pode ser usado para nomes de variáveis, nomes de métodos e nomes de pacotes. Por exemplo, var var = 1;
é uma declaração Java válido, mas tentando declarar uma classe como public class var {}
resulta em um erro: as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
. Atualizei a resposta acima para entrar em mais detalhes sobre a lógica por trás var
do Java e suas diferenças com o var
C #.
Ele será suportado no JDK 10. É ainda possível vê-lo em ação na compilação de acesso antecipado .
O JEP 286 :
Aprimore a linguagem Java para estender a inferência de tipo para declarações de variáveis locais com inicializadores.
Então agora, em vez de escrever:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Você escreve:
var list = new ArrayList<String>();
var stream = myStream();
Notas:
var
agora é um nome de tipo reservadoSe você quiser experimentá-lo sem instalar o Java em seu sistema local, criei uma imagem do Docker com o 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 ==> []
var
) não é equivalente. No var
exemplo list
é do tipo ArrayList
, não a List
.
Uma solução simples (supondo que você esteja usando um IDE decente) é apenas digitar 'int' em todos os lugares e depois definir o tipo para você.
Na verdade, acabei de adicionar uma classe chamada 'var' para não precisar digitar algo diferente.
O código ainda é muito detalhado, mas pelo menos você não precisa digitá-lo!
int
) - estou perdendo alguma coisa? (*: Embora eu nunca chamaria Eclipse uma IDE decente, não posso julgar por outros ...)
O Java 10 obteve inferência de tipo de variável local, agora ele possui var
praticamente o equivalente ao C # one (tanto quanto sei).
Também pode inferir tipos não denotáveis (tipos que não puderam ser nomeados nesse local pelo programador; apesar de que tipos não denotáveis são diferentes). Veja, por exemplo, Truques com var
classes anônimas (que você nunca deve usar no trabalho) .
A única diferença que pude encontrar é que em C #,
No Java 10 var
não é um nome de tipo legal.
A partir de Java 10, o equivalente é ... var
.
Eu sei que isso é mais antigo, mas por que não criar uma classe var e criar construtores com tipos diferentes e dependendo de quais construtores são chamados, você obtém var com tipos diferentes. Você pode até criar métodos para converter um tipo em outro.
Lombok
suporta var, mas ainda é classificado 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);
Aqui está uma armadilha a evitar ao tentar usá-lo IntelliJ IDEA
. Parece funcionar como esperado, incluindo a conclusão automática e tudo mais. Até que exista uma solução "não-hacky" (por exemplo, devido ao JEP 286: Inferência de tipo de variável local ), essa pode ser sua melhor aposta agora.
Observe que também val
é Lombok
suportado sem modificar ou criar um lombok.config
.
Você pode, no Java 10, mas apenas para variáveis locais , significando,
Você pode,
var anum = 10; var aString = "Var";
Mas não pode,
var anull = null; // Since the type can't be inferred in this case
Confira as especificações para mais informações.
var
pode ser usado para muitas formas de tipos não denotáveis, incluindo tipos de captura, tipos de interseção e tipos de classe anônimos. E, a partir do Java 11, também pode ser aplicado aos parâmetros lambda.
Em geral, você pode usar a classe Object para qualquer tipo, mas pode fazer a conversão de tipo mais tarde!
por exemplo:-
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);
var
palavra agora oficialmente no idioma, sua resposta também se refere à maneira antiquada.
Agora, esse recurso está disponível no Java SE 10. O var estático, com segurança de tipo, finalmente chegou ao mundo java :)
fonte: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(ouvar
) se você usa uma linguagem "Java de substituição" específica ;-) #