Existe inferência automática de tipo em Java?

113

Existe um autotipo de variável em Java como você tem em C ++?

Um exemplo:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Eu sei que existe um loop for aprimorado em Java, mas existe um auto? Se não, existe um hack para fazer isso? Estou me referindo ao novo recurso em C ++ 11

Jogos Brainiac
fonte
1
Tudo, exceto os tipos fundamentais, podem ser atribuídos a uma variável de tipo Object, portanto, para algumas operações, você pode usar Objectonde quiser auto.
Zyx 2000,
1
nenhum java não tem essa variável
Aleksei Bulgak
@ Zyx2000: Então, ele usará a to_stringfunção do objeto , e não o objeto real em questão, não é?
Games Brainiac
2
@GamesBrainiac: Não, ele usará a versão substituída, se houver.
Keppil
2
O termo que você está procurando não é "automático", é "inferência de tipo". Existem algumas perguntas sobre inferência de tipo em Java, embora se refiram principalmente a genéricos, então não tenho certeza de como encontrar uma duplicata ...

Respostas:

49

Respondido antes de a pergunta ser EDITADA :

Não, não há autotipo de variável em Java. O mesmo loop pode ser alcançado como:

for ( Object var : object_array)
  System.out.println(var);

Java possui variáveis ​​locais, cujo escopo está dentro do bloco onde foram definidas. Semelhante a C e C ++, mas não há palavra-chave auto ou register. No entanto, o compilador Java não permitirá o uso de uma variável local não explicitamente inicializada e fornecerá um erro de compilação (ao contrário de C e C ++, onde o compilador normalmente fornecerá apenas um aviso). Cortesia: Wikipedia .

Não, não há nenhuma inferência de tipo convencional em Java como C ++. Houve um RFE, mas foi fechado como "Não será corrigido", o motivo fornecido foi:

Os humanos se beneficiam da redundância da declaração de tipo de duas maneiras. Primeiro, o tipo redundante serve como documentação valiosa - os leitores não precisam pesquisar a declaração de getMap () para descobrir que tipo ela retorna. Em segundo lugar, a redundância permite que o programador declare o tipo pretendido e, assim, se beneficie de uma verificação cruzada realizada pelo compilador.

PATETA
fonte
10
@GamesBrainiac Não, as chamadas de método são sempre polimórficas em Java. No entanto, muitas outras coisas (por exemplo, resolução de sobrecarga ou qualquer operação não definida Object) não podem ser feitas assim. Essa não é realmente uma boa resposta; ela só funciona porque o exemplo na pergunta é fraco.
10
Esta questão é sobre a inferência de tipo em C ++ 11, não sobre o uso antigo de autoem C e pré-C ++ 11. Sua edição está fora do tópico.
4
"Não foi isso que eu quis dizer, uma vez que você digite lançá-lo em um objeto, ele lhe dará o to_string do objeto" False. Absolutamente 100% falso.
Louis Wasserman
140
"Os humanos se beneficiam com a redundância." É verdade. Todas as manhãs acordo e penso "como posso tornar o meu código mais redundante?". Por causa dos benefícios.
ahoffer
2
Além disso, essa resposta é obsoleta porque varé uma palavra-chave reservada desde Java 9.
6infinity8
69

Pode ser que o Java 10 tenha o que você (e eu) queremos, por meio da varpalavra - chave.

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

Das propostas de aprimoramento JDK 286


Atualização: Yap, esse recurso foi incluído na versão Java 10!

desculpemissjackson
fonte
6
Sim, é uma melhoria, mas essa palavra-chave só funciona com variáveis ​​locais. Não é tão poderoso quanto a inferência de tipo automático C ++
texasbruce
7
Pequenos detalhes: varnão é uma palavra-chave! Do JLS : "var não é uma palavra-chave, mas sim um identificador com significado especial como o tipo de declaração de uma variável local". Assim, ao contrário das palavras-chave, não há nada que o impeça de chamar uma variável ou método de "var".
Klitos Kyriacou
2
Bom ponto @KlitosKyriacou. No entanto, se eu imaginar substituir 'palavra-chave' por 'identificador' - ou mesmo 'identificador com significado especial como o tipo de declaração de uma variável local' - a resposta seria menos clara, eu acho. Mas sim, de varfato não está na lista de palavras-chave.
desculpemissjackson
Não é uma palavra-chave apenas para compatibilidade com versões anteriores. Além do fato de que você pode ter um identificador com este nome, var serve como uma palavra-chave.
facetus
25

Java 7 apresenta a sintaxe diamante

Box<Integer> integerBox = new Box<>(); // Java 7

Em comparação com o antigo java

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

O leitor crítico notará que essa nova sintaxe não ajuda a escrever os loops for na questão original. Isso parece correto e totalmente intencional. Veja a outra resposta que cita o banco de dados de bugs da Oracle.

Tarrasch
fonte
4
Verdade, mas o que ele (e eu) estamos procurando é algo como auto integerBox = new Box<Integer>();HashMap<String, LinkedList<Operation, Set<Integer>>>
:,
1
Essa preocupação é exatamente o que abordei após os exemplos de código. A conclusão foi que Java não faz isso, e isso de propósito.
Tarrasch
18

No Java 8, você pode usar a inferência de tipo lambda para evitar a declaração do tipo. O análogo aos exemplos do questionador seria:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

ambos também podem ser simplificados usando referências de método:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);
Ajit George
fonte
8

Resumindo, não, não existe um tipo automático. Se tudo o que você está fazendo é imprimir o valor, você pode apenas referir-se ao valor como um Object.

SimonC
fonte
ou computando hashCodes, ou coletando nomes de classes, ou ... você teve a ideia;) A lista é curta, no entanto. Veja a documentação da classe Object (comentário destinado a iniciantes, tenho certeza que você sabia disso SimonC)
Alexander Malakhov
4

Não é uma solução Java pura, no entanto, adicionar uma biblioteca chamada lombok permitirá que a mágica abaixo compile e funcione de forma muito semelhante à autopalavra - chave em C ++

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
samvel1024
fonte