Por que as variables ​​locais, incluindo as primitivas, devem sempre ser inicializadas em Java?

Por que as variables ​​locais, incluindo as primitivas, devem sempre ser inicializadas em Java? Por que o mesmo não é aplicável no caso de variables ​​de instância?

Houve uma pergunta sobre isso muito recentemente para C # … – leia as respostas lá também, como é basicamente a mesma coisa. Você também pode achar interessante a postagem recente do blog de Eric Lippert ; é pelo menos em torno da mesma área, embora tenha um impulso um pouco diferente.

Basicamente, exigir que uma variável seja atribuída a um valor antes de você lê-lo é uma coisa boa. Isso significa que você não vai ler acidentalmente algo que não pretendia. Sim, as variables ​​podem ter valores padrão – mas não é melhor para o compilador conseguir capturar seu erro, se ele puder provar que você está tentando ler algo que ainda não tenha sido atribuído? Se você quiser dar a uma variável local um valor padrão, você sempre pode atribuir isso explicitamente.

Agora, tudo bem para variables ​​locais – mas, por exemplo, e variables ​​estáticas, o compilador não tem como saber a ordem na qual os methods serão chamados. Uma propriedade “setter” será chamada antes do “getter”? Não tem como saber, por isso não há como alertá-lo para o perigo. É por isso que os valores padrão são usados ​​para variables ​​de instância / estática – pelo menos você obterá um valor conhecido (0, falso, nulo, etc) em vez de apenas “o que quer que esteja na memory no momento”. (Também remove o possível problema de segurança de ler dados confidenciais que não foram explicitamente apagados.)

Bem, no caso de variables ​​locais, fica claro o que significa ‘antes’, já que o stream do programa entre declaração (no método) e referência é seqüencial. No caso de campos declarados fora do compilador de método, nunca se sabe qual código será usado quando assim ele não pode gerar um erro, pois possivelmente algum outro método irá inicializar o campo antes de ser usado.

Em Java, as variables ​​de class e instância assumem um valor padrão (null, 0, false) se não forem inicializadas manualmente. No entanto, as variables ​​locais não possuem um valor padrão. A menos que uma variável local tenha recebido um valor, o compilador se recusará a compilar o código que a lê. IMHO, isso leva à conclusão de que inicializar uma variável local com algum valor padrão (como null, que pode levar a uma NullPointerException posteriormente) quando ela é declarada é realmente uma coisa ruim. Considere o seguinte exemplo:

Object o; if () o = ; else o = ; System.out.println(o); 

Uma boot de o com null é completamente desnecessária, uma vez que o compilador Java verifica em tempo de compilation que qualquer caminho de código inicializa o (com valor nulo ou algum valor não nulo) antes que a variável seja lida. Isso significa que o compilador se recusará a compilar a linha System.out.println(o); se você comentar qualquer uma das duas inicializações da variável o no snippet de código acima.

Isso vale para o Java e talvez apenas para o Java. Eu não sei sobre linguagem como c #. No bom e velho C (e talvez C ++), no entanto, ainda é recomendado sempre inicializar as variables ​​ao declará-las, AFAIK. Essas linguagens de programação “old-school” podem ser a razão, que a recomendação de sempre inicializar variables ​​aparece em livros e discussões sobre linguagens modernas como Java, onde a compilation registra se uma variável foi inicializada ou não.

Não é totalmente verdade. Variáveis ​​locais só precisam ser inicializadas se forem referência. Uma variável local pode ser deixada não inicializada se nunca for referenciada. Por exemplo:

 int x; // Valid int y; println("y=" + y); // Not valid since y's value has never been assigned 

Variáveis ​​locais e primitivos devem ser inicializados antes do uso, porque você saberia o que esperar dos valores. Historicamente, quando uma nova variável foi criada, ela conteria valores randoms da memory [e não se poderia prever o valor]. Java também requer isso porque evita a presença de variables ​​órfãs.

Na prática, todas as variables ​​precisam ser inicializadas antes de usá-las.

Não consigo pensar em uma hora em que você deseja usar uma variável antes de definir seu valor (a menos que você esteja comparando-a com nulo).

É necessário inicializar variables ​​locais (somente quando as usamos) porque elas não recebem nenhum valor padrão como variables ​​de instância.

E como regra básica, devemos sempre inicializar qualquer variável antes de usá-la. Caso contrário, pode resultar em um erro como nullPointer, etc

Agora, por que as variables ​​locais não recebem valor padrão? O motivo é que as variables ​​locais residem na pilha e são visíveis apenas no contexto do método local, ao contrário das variables ​​de instância que residem no heap e possuem escopo em todo o programa.

Então, quando a pilha finalizar, o valor do método local também será destruído: 1] Eles devem ser inicializados explicitamente (quando os usarmos) 2] Eles não devem ser inicializados implicitamente (por nulo, 0 ou falso) como variables ​​de instância