2010-01-03 5 views
1

Я хочу метод, который может вызывать любые Throwable, включая подкласс Exception. Ive получил что-то, что принимает исключение, заставляет его в потоке локально, а затем вызывает class.newInstance. Этот класс ctor объявляет, что он выбрасывает Exception, а затем принимает threadlocal и бросает его. Проблема в том, что это не работает для двух объявленных исключений, которые были выбраны Class.newInstance(), а именно IllegalAccessException и InstantiationException.Магический метатор исключения без объявления бросков Исключение

Я предполагаю, что любой другой метод с использованием некоторого класса sun.* - это просто взломать и не очень надежный.

Обертывание это не вариант, потому что это означает, что ловцы ловить тип различий, и это слишком простой и скучный ...

static public void impossibleThrow(final Throwable throwable) { 
    Null.not(throwable, "throwable"); 
    if (throwable instanceof RuntimeException) { 
     throw (RuntimeException) throwable; 
    } 
    if (throwable instanceof Error) { 
     throw (Error) throwable; 
    } 
    try { 
     THROW.set((Exception) throwable); 
     THROWER.newInstance(); 
    } catch (final InstantiationException screwed) { 
     throw new Error(screwed); 
    } catch (final IllegalAccessException screwed) { 
     throw new Error(screwed); 
    } finally { 
     THROW.remove(); 
    } 
} 

private final static Class<Impossible> THROWER = Impossible.class; 
private final static ThreadLocal<Exception> THROW = new ThreadLocal<Exception>(); 

static private class Impossible { 

    @SuppressWarnings("unused") 
    public Impossible() throws Exception { 
     throw THROW.get(); 
    } 
} 
+2

Я не могу получить то, что вы пытаетесь добиться .. – Bozho

+0

Я не могу себе представить, почему это может быть полезно. – duffymo

+0

Я думаю, что это просто для удовольствия. Как вы можете выбросить проверенное исключение, не объявив его в кавычки? –

ответ

3

От Java Puzzlers (головоломка 43):

public static void impossibleThrow(Throwable t) 
{ 
    Thread.currentThread().stop(t); // Deprecated method. 
} 

В книге показана другие способы достижения тех же задач, один является упрощенной версией ваших, других эксплойты общего типа стирание бросить любую Throwable, где ожидается ошибка.

+0

Будет ли это звучать как победитель, обертка слишком простая и не совсем такая же. –

3

Если вы хотите Exception пузырь через код не ожидая, что исключение, то просто оберните его в RuntimeException

} catch (RuntimeException e) { 
    throw e; // only wrap if needed 
} catch (Exception e) { 
    throw new RuntimeException("FOO went wrong", e); 
} 

Помните, что сообщение должно быть информативным. В какой-то день вам придется исправить ошибку, основанную только на информации в трассировке стека.

3

Обход исключения из исключения RuntimeException (как предлагает Thorbjørn) - это путь. Тем не менее, вы обычно хотите сохранить стек из оригинального excpetion. Вот как:

public static void rethrow(final Throwable t) 
    { 
    if(t instanceof RuntimeException) 
     throw (RuntimeException) t; 

    RuntimeException e = new RuntimeException(t); 
    e.setStackTrace(t.getStackTrace()); 
    throw e; 
    } 
0

Я исправил javac, чтобы удалить ошибку, скомпилировал impossibleThrow(), переименовал исходный файл в то, что не заканчивается на .java (что вынуждает следующий компилятор использовать существующий .class) и использовал это.

0

В качестве инструмента для отладки существует некоторый валидность для этого вопроса. Предположим, вы работаете с каким-то кодом, который может быть неудачным, и вы видите, что он (возможно) ловит определенные исключения и (возможно) выдает определенные исключения. Вы подозреваете, что неожиданное исключение не было обнаружено. Однако базовый код/​​система слишком сложна, и ошибка слишком прерывистая, чтобы вы могли пройти через отладчик. Может быть полезно добавить бросание исключения без изменения метода любым другим способом. В этом случае обертка исключения с RuntimeException не будет работать, потому что вы хотите, чтобы вызывающие методы вели себя нормально.

Смежные вопросы