Возможно ли отключение проверенных исключений в Java?
Я читал статью о проверенных и непроверенных исключениях в Java и нашел эту статью / ссылку: https://projectlombok.org/disableCheckedExceptions.html
Согласно статье, это просто хак, разработанный для javac.
Рассмотрим фрагмент кода ниже:
import java.io.*;
class Example
{
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("myfile.txt");
int k;
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}
}
Здесь я должен написать public static void main(String args[]) throws IOException
потому что я пытаюсь открыть файл. Здесь предложение "throws" является обязательным. Без этого я получу ошибку. Что делать, если я уверен в наличии файла, который открываю. iemyfile.txt в указанном месте. В какой-то момент можно почувствовать, что несколько проверенных исключений не требуются для кода.
Есть ли в Java средство для отключения проверенных исключений в соответствии с необходимостью?
Даже после такого большого исследования я не мог найти правильный ответ для этого.
2 ответа
Есть ли в Java средство для отключения проверенных исключений в соответствии с необходимостью?
Нет официальных средств, но есть обходные пути, которые можно использовать при необходимости:
Во-первых, поскольку в java есть как проверенные, так и непроверенные исключения, использование непроверенных исключений может быть вариантом. Все исключения, которые происходят из RuntimeException, не проверяются:
RuntimeException является суперклассом тех исключений, которые могут быть выброшены во время нормальной работы виртуальной машины Java. Метод не обязан объявлять в своем предложении throws любые подклассы RuntimeException, которые могут быть выброшены во время выполнения метода, но не перехвачены.
Интересно почитать здесь, здесь.
Затем есть стирание типа, которое позволяет генерировать проверенное исключение, не объявляя его.
Это то, что проект lombok использует для @SneakyThrows
import lombok.SneakyThrows;
public class SneakyThrowsExample implements Runnable {
@SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
@SneakyThrows
public void run() {
throw new Throwable();
}
}
Используйте с осторожностью:
Имейте в виду, что невозможно ловить скрытно брошенные проверенные типы напрямую, так как javac не позволит вам написать блок catch для типа исключения, который ни один вызов метода в теле try не объявляет как выброшенный.
И, наконец, только проверенный исключитель заботится о компиляторе, он вообще не является частью jvm. Как только вы пройдете этап компиляции, все станет возможным. Таким образом, написание байт-кода напрямую или использование версии javac с отключенными проверенными исключениями полностью обходит их.
Кроме взлома компилятора, нет возможности отключить проверенные исключения, о которых я знаю. Лучшее, что вы можете сделать, это перехватить проверенное исключение и повторно выбросить его в исключение времени выполнения, если вы не хотите, чтобы клиентский код обрабатывал проверенное исключение.
Используйте плагин компилятора Manifold с
exceptions
опция плагина. Эффективно нейтрализует проверенные исключения. С этой опцией отмеченные исключения ведут себя как непроверенные исключения. Больше никаких ошибок компилятора, больше нет шаблонной попытки try/catch/wrap/rethrow. Работает с Java 8 - 12.