A ideia por trás das variáveis locais é que elas existem apenas dentro do escopo limitado para o qual são necessárias. Como tal, deve haver pouca razão para incerteza quanto ao valor, ou pelo menos, de onde esse valor está vindo. Eu poderia imaginar muitos erros decorrentes de ter um valor padrão para variáveis locais.
Por exemplo, considere o seguinte código simples ... ( NB, vamos supor, para fins de demonstração, que variáveis locais recebem um valor padrão, conforme especificado, se não inicializado explicitamente )
System.out.println("Enter grade");
int grade = new Scanner(System.in).nextInt(); //I won't bother with exception handling here, to cut down on lines.
char letterGrade; //let us assume the default value for a char is '\0'
if (grade >= 90)
letterGrade = 'A';
else if (grade >= 80)
letterGrade = 'B';
else if (grade >= 70)
letterGrade = 'C';
else if (grade >= 60)
letterGrade = 'D';
else
letterGrade = 'F';
System.out.println("Your grade is " + letterGrade);
Quando tudo estiver dito e feito, assumindo que o compilador atribuiu um valor padrão de '\ 0' para letterGrade , este código como escrito funcionaria corretamente. No entanto, e se esquecermos a instrução else?
Uma execução de teste do nosso código pode resultar no seguinte
Enter grade
43
Your grade is
Esse resultado, embora fosse esperado, certamente não era a intenção do codificador. De fato, provavelmente na grande maioria dos casos (ou pelo menos em um número significativo), o valor padrão não seria o valor desejado , portanto, na grande maioria dos casos, o valor padrão resultaria em erro. Faz mais sentido forçar o codificador a atribuir um valor inicial a uma variável local antes de usá-la, uma vez que a dificuldade de depuração causada pelo esquecimento do = 1
in for(int i = 1; i < 10; i++)
supera em muito a conveniência de não ter que incluir o = 0
in for(int i; i < 10; i++)
.
É verdade que os blocos try-catch-finally podem ficar um pouco confusos (mas não é realmente um catch-22 como a citação parece sugerir), quando, por exemplo, um objeto lança uma exceção verificada em seu construtor, ainda para um razão ou outra, algo deve ser feito a este objeto no final do bloco em finalmente. Um exemplo perfeito disso é quando se trata de recursos, que devem ser fechados.
Uma maneira de lidar com isso no passado pode ser assim ...
Scanner s = null; //declared and initialized to null outside the block. This gives us the needed scope, and an initial value.
try {
s = new Scanner(new FileInputStream(new File("filename.txt")));
int someInt = s.nextInt();
} catch (InputMismatchException e) {
System.out.println("Some error message");
} catch (IOException e) {
System.out.println("different error message");
} finally {
if (s != null) //in case exception during initialization prevents assignment of new non-null value to s.
s.close();
}
No entanto, a partir do Java 7, este bloco finalmente não é mais necessário usando try-with-resources, dessa forma.
try (Scanner s = new Scanner(new FileInputStream(new File("filename.txt")))) {
...
...
} catch(IOException e) {
System.out.println("different error message");
}
Dito isso, (como o nome sugere) isso só funciona com recursos.
E embora o exemplo anterior seja um pouco nojento, talvez isso fale mais sobre a maneira como try-catch-finally ou essas classes são implementadas do que sobre variáveis locais e como elas são implementadas.
É verdade que os campos são inicializados com um valor padrão, mas isso é um pouco diferente. Quando você diz, por exemplo, int[] arr = new int[10];
assim que inicializa este array, o objeto existe na memória em um determinado local. Vamos supor por um momento que não haja valores padrão, mas, em vez disso, o valor inicial é qualquer série de 1s e 0s que esteja naquele local de memória no momento. Isso pode levar a um comportamento não determinístico em vários casos.
Suponha que temos ...
int[] arr = new int[10];
if(arr[0] == 0)
System.out.println("Same.");
else
System.out.println("Not same.");
Seria perfeitamente possível que Same.
fosse exibido em uma execução e Not same.
pudesse ser exibido em outra. O problema pode se tornar ainda mais grave quando você começar a falar sobre variáveis de referência.
String[] s = new String[5];
De acordo com a definição, cada elemento de s deve apontar para uma String (ou é nulo). No entanto, se o valor inicial for qualquer série de 0s e 1s que ocorra neste local da memória, não apenas não há garantia de que você obterá os mesmos resultados todas as vezes, mas também não há garantia de que o objeto s [0] aponta to (assumindo que aponta para algo significativo) até mesmo é um String (talvez seja um Coelho,: p )! Essa falta de preocupação com o tipo iria contra quase tudo que faz o Java Java. Portanto, embora ter valores padrão para variáveis locais possa ser visto como opcional, na melhor das hipóteses, ter valores padrão para variáveis de instância é mais próximo de uma necessidade .