Ide di balik variabel lokal adalah variabel tersebut hanya ada di dalam ruang lingkup terbatas yang dibutuhkannya. Dengan demikian, harus ada sedikit alasan untuk ketidakpastian mengenai nilai, atau setidaknya, dari mana nilai itu berasal. Saya bisa membayangkan banyak kesalahan yang timbul karena memiliki nilai default untuk variabel lokal.
Misalnya, pertimbangkan kode sederhana berikut ... ( NB mari kita asumsikan untuk tujuan demonstrasi bahwa variabel lokal diberi nilai default, seperti yang ditentukan, jika tidak diinisialisasi secara eksplisit )
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);
Ketika semua dikatakan dan dilakukan, dengan asumsi kompilator menetapkan nilai default '\ 0' ke letterGrade , kode ini seperti yang tertulis akan berfungsi dengan baik. Namun, bagaimana jika kita lupa pernyataan lain?
Uji coba kode kami mungkin menghasilkan hal berikut
Enter grade
43
Your grade is
Hasil ini, meskipun sudah diharapkan, pasti bukan maksud pembuat kode. Memang, mungkin dalam sebagian besar kasus (atau setidaknya, jumlah yang signifikan, daripadanya), nilai default bukanlah nilai yang diinginkan , jadi dalam sebagian besar kasus, nilai default akan menghasilkan kesalahan. Lebih masuk akal untuk memaksa pembuat kode untuk menetapkan nilai awal ke variabel lokal sebelum menggunakannya, karena kesedihan debugging yang disebabkan oleh lupa = 1
dalam for(int i = 1; i < 10; i++)
jauh lebih besar daripada kenyamanan karena tidak harus menyertakan = 0
in for(int i; i < 10; i++)
.
Memang benar bahwa blok coba-tangkap-akhirnya bisa menjadi sedikit berantakan (tetapi sebenarnya ini bukan tangkapan-22 seperti yang tampaknya disarankan oleh kutipan), ketika misalnya sebuah objek melempar pengecualian yang dicentang dalam konstruktornya, namun untuk satu alasan atau lainnya, sesuatu harus dilakukan untuk objek ini pada akhirnya blok pada akhirnya. Contoh sempurna dari ini adalah ketika berhadapan dengan sumber daya, yang harus ditutup.
Salah satu cara untuk menangani ini di masa lalu mungkin seperti itu ...
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();
}
Namun, pada Java 7, blok terakhir ini tidak lagi diperlukan menggunakan try-with-resources, seperti itu.
try (Scanner s = new Scanner(new FileInputStream(new File("filename.txt")))) {
...
...
} catch(IOException e) {
System.out.println("different error message");
}
Yang mengatakan, (seperti namanya) ini hanya berfungsi dengan sumber daya.
Dan sementara contoh pertama agak menjijikkan, ini mungkin lebih mengacu pada cara coba-tangkap-akhirnya atau kelas-kelas ini diimplementasikan daripada berbicara tentang variabel lokal dan bagaimana mereka diimplementasikan.
Memang benar bahwa bidang diinisialisasi ke nilai default, tetapi ini sedikit berbeda. Saat Anda mengatakan, misalnya, int[] arr = new int[10];
segera setelah Anda menginisialisasi larik ini, objek tersebut ada dalam memori di lokasi tertentu. Mari kita asumsikan sejenak bahwa tidak ada nilai default, tetapi nilai awalnya adalah deretan 1 dan 0 apa pun yang kebetulan ada di lokasi memori tersebut saat ini. Hal ini dapat menyebabkan perilaku non-deterministik dalam beberapa kasus.
Misalkan kita memiliki ...
int[] arr = new int[10];
if(arr[0] == 0)
System.out.println("Same.");
else
System.out.println("Not same.");
Sangat mungkin bahwa Same.
mungkin ditampilkan dalam satu proses dan Not same.
mungkin ditampilkan di proses lain. Masalahnya bisa menjadi lebih menyedihkan setelah Anda mulai berbicara tentang variabel referensi.
String[] s = new String[5];
Menurut definisi, setiap elemen s harus mengarah ke String (atau null). Namun, jika nilai awalnya adalah rangkaian 0 dan 1 apa pun yang terjadi di lokasi memori ini, tidak hanya tidak ada jaminan Anda akan mendapatkan hasil yang sama setiap saat, tetapi juga tidak ada jaminan bahwa objek s [0] menunjuk to (dengan asumsi itu menunjuk ke sesuatu yang berarti) bahkan adalah String (mungkin itu Kelinci,: p )! Kurangnya perhatian terhadap tipe ini akan berhadapan dengan hampir semua yang membuat Java Java. Jadi meskipun memiliki nilai default untuk variabel lokal dapat dilihat sebagai pilihan terbaik, memiliki nilai default untuk variabel instan lebih mendekati kebutuhan .