Проверенное исключение не генерируется и превращается в RuntimeException - PullRequest
0 голосов
/ 06 января 2019

Что здесь происходит?

Почему проверенный дочерний элемент IOException (RemoteException) преобразуется в RuntimeException?

Фрагмент, взятый из здесь

import java.rmi.RemoteException;

class Thrower {
    public static void spit(final Throwable exception) {
        class EvilThrower<T extends Throwable> {
            @SuppressWarnings("unchecked")
            private void sneakyThrow(Throwable exception) throws T {
                throw (T) exception; // something interesting 
            }
        }
        new EvilThrower<RuntimeException>().sneakyThrow(exception);
    }
}

public class ThrowerSample {
    public static void main( String[] args ) {
        Thrower.spit(new RemoteException("go unchecked!"));
    }
}

1 Ответ

0 голосов
/ 06 января 2019

Что здесь происходит?

Этот код обходит Проверка исключений во время компиляции .

Почему это может быть полезно?

Не всегда удобно работать с API, использующим проверенные исключения.

Один из самых известных примеров - JDBC . Работа с jdbc всегда требует от разработчика иметь дело с SQLException. Но обычно вы не знаете, что делать, за исключением.

Или если вы работаете с библиотекой, в которой разработчики решили наследовать свои исключения от Exception, а не RuntimeException.


Почему проверенный ребенок IOException (RemoteException) конвертируется в RuntimeException?

Не конвертируется в RuntimeException.

Исключение составляет RemoteException:

Exception in thread "main" java.rmi.RemoteException: go unchecked!

Фрагмент кода использует общие приемы Java. Без строки @SuppressWarnings("unchecked") компилятор генерирует непроверенное предупреждение о приведении.

Головоломка 43

Фрагмент кода является одним из решений головоломки 43 из Java Puzzlers: ловушки, ловушки и угловые случаи :

// Don’t do this - circumvents exception checking!
public static void sneakyThrow(Throwable t) {
    Thread.currentThread().stop(t); // Deprecated!!
}

Можно написать метод, который функционально эквивалентен sneakyThrow без использования каких-либо устаревших методов. На самом деле, есть как минимум два способа сделать это. Один из них работает только в версии 5.0 и более поздних. Вы можете написать такой метод? Он должен быть написан на Java, а не на байт-коде JVM. Вы не должны изменять метод после того, как его клиенты скомпилированы. Ваш метод не должен быть идеальным: это приемлемо, если он не может выбросить один или два подкласса Exception.

Решение из книги с использованием дженериков:

// Don’t do this either - circumvents exception checking!
class TigerThrower<T extends Throwable> {
    public static void sneakyThrow(Throwable t) {
        new TigerThrower<Error>().sneakyThrow2(t);
    }
    private void sneakyThrow2(Throwable t) throws T {
        throw (T) t;
    }
}

Примечание по этому решению из книги:

Предупреждение - это способ компилятора сказать вам, что вы, возможно, стреляете сами в ногу, и на самом деле вы есть. Непроверенное предупреждение о касте говорит вам, что рассматриваемый актерский состав не будет проверен во время выполнения. Когда вы получаете непроверенный произнесите предупреждение, измените программу, чтобы устранить ее, или убедите себя актерский состав не может потерпеть неудачу

Таким образом, проверка исключений в Java не осуществляется виртуальным машина. Это средство времени компиляции, предназначенное для облегчения написания правильных программы, но это можно обойти во время выполнения. Чтобы уменьшить вашу экспозицию, не игнорировать предупреждения компилятора.


Смотри также:

@SneakyThrows

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...