Pengecualian diperiksa dan tidak
Singkatnya, pengecualian diperlukan untuk memisahkan skenario positif (ketika semuanya berjalan dengan baik) dari negatif (ketika kesalahan terjadi dan skenario positif terputus). Ini berguna karena sangat sering ada sedikit informasi dalam kode untuk menangani kesalahan dan Anda perlu menyampaikan informasi tentang apa yang terjadi di atas.
Misalnya, ada fungsi untuk membaca angka dari file (atau bukan angka, tidak masalah):
String readStoredData(String id) throws FileNotFoundException, IOException {
File file = new File(storage, id + ".dat");
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
return in.readLine();
}
}
Seperti yang Anda lihat, tidak ada kode di sini yang memutuskan apa yang harus dilakukan jika terjadi kesalahan. Dan tidak jelas apa yang harus dilakukan - menghentikan program, mengembalikan "", null atau yang lainnya? Oleh karena itu, pengecualian dideklarasikan throws
dan akan ditangani di suatu tempat di pemanggil:
int initCounter(String name) throws IOException, NumberFormatException {
try {
return Integer.parseInt(readStoredData(name));
} catch (FileNotFoundException e) {
return 0;
}
}
Pengecualian di Jawa dibagi menjadi dicentang dan tidak dicentang. Dalam hal ini, IOException
ini dicentang - Anda harus mendeklarasikannya throws
dan kemudian memprosesnya di suatu tempat, kompilator akan memeriksanya. NumberFormatException
unverifiable - pemrosesannya tetap pada hati nurani programmer dan compiler tidak akan mengontrol Anda.
Ada juga jenis pengecualian ketiga - kesalahan fatal ( Error
), tetapi biasanya tidak masuk akal untuk ditangani, jadi Anda tidak perlu mengkhawatirkannya.
, â , .
:
;
( â ) .
- , . .
Scala?
Scala: ( ), .
Try[T]
â , , . Scala:
def readStoredData(id: String): Try[String] =
Try {
val file = new File(storage, s"$id.dat")
val source = Source.fromFile(file)
try source.getLines().next()
finally source.close()
}
def initCounter(name: String): Try[Int] = {
readStoredData(name)
.map(_.toInt)
.recover {
case _: FileNotFoundException => 0
}
}
, , readStoredData
String
, Try[String]
â . Try Java â , .
:
(
Either[Error, T]
, );
happy-path , (
Try/get
for/map/flatMap
);
Java - , ( Java , ).
( Try[String]
â ). Option[T]
â , Future[T]
â ..
, â . / Java, ( ).
:
FileNotFoundException
,
IOException
â
:
def readStoredData(id: String): Option[Try[String]] = {
val file = new File(storage, s"$id.dat")
if (file.exists()) Some(
Try {
val source = Source.fromFile(file)
try source.getLines().next()
finally source.close()
}
)
else None
}
Option[Try[String]]
, , :
None
â
Some(Success(string))
â
Some(Failure(exception))
â ,
Try
. Java , null. .
Banyaknya tipe menciptakan lebih banyak gangguan visual dan seringkali membutuhkan kode yang lebih kompleks saat bekerja dengan banyak efek pada saat yang bersamaan. Tetapi sebagai imbalannya, ia menyediakan kode yang mendokumentasikan sendiri dan memungkinkan kompilator menemukan banyak kesalahan.