Yerel değişkenlerin arkasındaki fikir, yalnızca ihtiyaç duydukları sınırlı kapsam içinde var olmalarıdır. Bu nedenle, değere ilişkin belirsizlik için çok az neden olmalıdır veya en azından bu değerin nereden geldiği. Yerel değişkenler için varsayılan bir değere sahip olmaktan kaynaklanan birçok hatayı hayal edebiliyorum.
Örneğin, aşağıdaki basit kodu göz önünde bulundurun ... ( NB, açık bir şekilde başlatılmamışsa, yerel değişkenlere belirtildiği gibi varsayılan bir değer atandığını gösterme amacıyla varsayalım )
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);
Her şey söylendiğinde ve yapıldığında, derleyicinin letterGrade'e varsayılan bir '\ 0' değeri atadığını varsayarak , bu kod yazıldığı şekliyle düzgün çalışacaktır. Ancak, ya else ifadesini unutursak?
Kodumuzun bir test çalıştırması aşağıdakilere neden olabilir:
Enter grade
43
Your grade is
Bu sonuç, bekleneceği gibi, kesinlikle kodlayıcının niyeti değildi. Aslında, muhtemelen çoğu durumda (veya en azından önemli bir sayıda) varsayılan değer istenen değer olmayacaktır , bu nedenle çoğu durumda varsayılan değer hatayla sonuçlanacaktır. Bu unutulması neden ayıklama acı için, kullanmadan önce yerel bir değişken bir başlangıç değeri atamak için kodlayıcı zorlamak için daha mantıklı = 1
olarak for(int i = 1; i < 10; i++)
uzakta bulunmaktadır zorunda değil kolaylık ağır basar = 0
içinde for(int i; i < 10; i++)
.
Try-catch-nihayet bloklarının biraz dağınık olabileceği doğrudur (ama alıntının önerdiği gibi aslında bir catch-22 değildir), örneğin bir nesne yapıcısına kontrol edilmiş bir istisna attığında, ancak biri için sebep veya başka bir şey , sonunda bloğun sonunda bu nesneye bir şey yapılmalıdır . Bunun mükemmel bir örneği, kapatılması gereken kaynaklarla uğraşırken verilebilir.
Bunu geçmişte halletmenin bir yolu böyle olabilirdi ...
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();
}
Bununla birlikte, Java 7'den itibaren, bu nihayet bloğu artık böyle kaynaklarla deneme kullanıldığında gerekli değildir.
try (Scanner s = new Scanner(new FileInputStream(new File("filename.txt")))) {
...
...
} catch(IOException e) {
System.out.println("different error message");
}
Bununla birlikte, (adından da anlaşılacağı gibi) bu yalnızca kaynaklarla çalışır.
Ve önceki örnek biraz iğrenç olsa da, bu belki de, yerel değişkenler ve bunların nasıl uygulandıklarından ziyade bu sınıfların uygulandığı yolu ya da dene-yakala biçiminden daha çok bahsediyor.
Alanların varsayılan bir değerle başlatıldığı doğrudur, ancak bu biraz farklıdır. Örneğin, int[] arr = new int[10];
bu diziyi başlatır başlatmaz dediğinizde, nesne belirli bir konumda bellekte var olur. Bir an için varsayılan değerlerin olmadığını varsayalım, ancak bunun yerine başlangıç değeri, o anda o bellek konumunda bulunan 1 ve 0 serisi ne olursa olsun. Bu, bazı durumlarda deterministik olmayan davranışlara yol açabilir.
Varsayalım ki ...
int[] arr = new int[10];
if(arr[0] == 0)
System.out.println("Same.");
else
System.out.println("Not same.");
Same.
Bir çalışmada Not same.
gösterilebilmesi ve bir başkasında gösterilmesi tamamen mümkündür . Referans değişkenlerden bahsetmeye başladığınızda sorun daha da ağır hale gelebilir.
String[] s = new String[5];
Tanıma göre, s'nin her bir öğesi bir String'i işaret etmelidir (veya boştur). Bununla birlikte, başlangıç değeri, bu bellek konumunda meydana gelen 0 ve 1 serileriyse, yalnızca her seferinde aynı sonuçları alacağınızın garantisi değil, aynı zamanda nesnenin s [0] puan alacağının garantisi de yoktur. hatta (bu, herhangi anlamlı işaret varsayarak) olan bir dize (belki de bir Tavşan, var : p )! Yazı tipine yönelik bu endişe eksikliği, Java Java'yı yapan hemen hemen her şeyin karşısında uçacaktır. Bu nedenle, yerel değişkenler için varsayılan değerlere sahip olmak en iyi ihtimalle isteğe bağlı olarak görülebilirken, örnek değişkenler için varsayılan değerlere sahip olmak bir zorunluluktur .