Ya tentu saja: static final
variabel dapat diinisialisasi dalam blok statis tapi.... anda memiliki implisit GOTOs dalam contoh (try/catch
pada dasarnya adalah sebuah 'GOTO menangkap jika sesuatu yang buruk terjadi').
Jika pengecualian dilemparkan anda final
variabel tidak akan diinisialisasi.
Perhatikan bahwa penggunaan statis konstruksi bertentangan Berorientasi Objek dogma. Hal ini dapat mempersulit anda untuk menguji dan membuat debugging lebih sulit.
Anda dapat melakukan ini, tetapi anda perlu untuk keluar dari blok statis dengan melemparkan pengecualian - anda dapat rethrow pengecualian yang tertangkap atau yang baru. Umumnya pengecualian ini harus menjadi RuntimeException
. Anda benar-benar tidak harus menangkap generik Pengecualian
tapi lebih spesifik pengecualian(s) yang mungkin dilemparkan dari dalam anda mencoba
blok. Akhirnya, jika statis penginisialisasi melempar pengecualian maka itu akan membuat kelas tidak dapat digunakan selama jangka tertentu karena JVM hanya akan mencoba untuk menginisialisasi kelas anda setelah. Upaya berikutnya untuk menggunakan kelas ini akan mengakibatkan pengecualian lain, seperti NoClassDefFoundError
.
Jadi, untuk bekerja, anda penginisialisasi harus membaca sesuatu seperti ini:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
Dengan asumsi bahwa InitializationFailedException
kebiasaan RuntimeException
, tapi anda bisa menggunakan yang sudah ada.
public class MyClass
{
private static final SomeClass myVar;
static
{
Object obj = null; // You could use SomeClass, but I like Object so you can reuse it
try
{
obj = new SomeClass(...);
}
catch(WhateverException err)
{
// Possibly nested try-catches here if the first exception is recoverable...
// Print an error, log the error, do something with the error
throw new ExceptionInInitializerError(err);
}
finally
{
myVar = (SomeClass) obj;
}
}
}
Dengan asumsi tidak ada di mana hulu berada dalam posisi untuk menangkap baik ExceptionInInitializationError atau umum Pengecualian maka program harus tidak pernah mencoba untuk menggunakan myVar. Namun jika mereka tertangkap dan program doesn't akhir, maka anda perlu kode untuk melihat dan menangani myVar menjadi nol (atau bahagia dengan NullPointerExceptions
keluar semua di atas).
I'm tidak yakin ada cara yang baik untuk menangani hal ini.