2015-06-28 8 views
0

Это упрощенный класс, который описывает мою проблему:Unhandled тип исключения Exception

public class Main { 

    enum Test{ 
     First(method()){ // Unhandled exception type Exception 
      // ... 
     }; 

     Test(Object obj){ 
      //... 
     } 
    } 

    static Object method() throws Exception{ 
     // ... 
     if (someCondition){ 
      throw new Exception(); 
     } 

    } 
} 

Над someCondition зависит от устройства и некоторых ситуациях, и я не могу решить, об этом сейчас, и как вы можете видеть, я не хотят ловить Exception в method.

+1

какой у вас вопрос? вы не хотите, чтобы это бросило? Я думаю, что java инициализирует, когда вы впервые ссылаетесь на класс, чтобы он мог выглядеть как исключение в случайных местах. – HuStmpHrrr

+0

@HuStmpHrrr Это ошибка компиляции. – hasanghaforian

+0

о, да. поскольку это проверенное исключение, поэтому оно не собирается компилироваться. вам нужно обернуть его над «RuntimeException», чтобы он мог тихо кинуть. – HuStmpHrrr

ответ

0

Да. Это ошибка компиляции.

№ Нет специального синтаксиса для решения этой проблемы.

Я не хочу ломать Исключение в методе.

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

В этом случае невозможно поймать проверенное исключение. Следовательно, если вы собираетесь вызвать метод в постоянном параметре enum (в соответствии с вашим кодом), метод не может выбросить исключенное исключение .

Вот возможный обходной путь, хотя это, вероятно, плохая идея:

public class Main { 

    enum Test{ 
     First(methodCatchingException()){ 
      // ... 
     }; 

     Test(Object obj){ 
      //... 
     } 
    } 

    static Object method() throws Exception{ 
     // ... 
     if (someCondition){ 
      throw new Exception(); 
     } 
    } 

    static Object methodCatchingException() { 
     try { 
      return method(); 
     } catch (Exception ex) { 
      throw new SomeRuntimeException("the sky is falling!", ex); 
     } 
    } 
} 

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

  • Вы не можете поймать его ... потому что enum инициализации как static инициализации.
  • Если Java-среда полностью игнорировала выброшенное исключение, это было бы очень плохо.
  • Если сбой во время выполнения Java, то модель проверенных исключений нарушена.

Итак, что это говорит мне, что дизайн Java язык является правильным, компилятор Java является правильным ... и реальная проблема здесь в приложении дизайн:

  • Вы не должны распространять проверенное исключение. Если в этом контексте возникает исключение, оно категорически НЕ является восстановимой ошибкой.

  • Возможно, нецелесообразно использовать перечисление для этого ... из-за возможной ошибки восстановления без восстановления.

(Обратите внимание, что, если этот метод вызов завершается из-за неконтролируемого исключение, она превратит его в ExceptionInInitializerError. Кроме того, виртуальная машина будет отмечать enum класс как uninitializable и выбросит NoClassDefFoundError, если ваше приложение попытки использовать его, например, через Class.forName(...).)


Я предполагаю, что Exception используется здесь для целей иллюстрации. Это плохая вещь, чтобы объявить методы, как throws Exception или throw new Exception(...)


1 - Я посмотрел на JLS за то, чтобы поддержать это. Насколько я могу судить, спецификация не упоминает эту ситуацию. Я бы ожидал увидеть его в списке JLS 11.2.3. Однако ясно, что компилятор не может разрешить проверенное исключение распространяться в этой точке, поскольку оно «сломает» модель того, как работают проверенные исключения.

+0

Благодарим вас за внимание, поскольку для исключения было выбрано 'Exception'. – hasanghaforian

0

Я не думаю, что вы хотите выбрасывать здесь исключенное исключение (вот что такое Exception). Причина: вы вызываете вызов method внутри конструктора Test. Там действительно нет чистого способа справиться с этим.

В то время как очевидным выбором здесь является переход на RuntimeException, я хочу, чтобы вы передумали бросать исключение в первую очередь. Поскольку в вашем перечислении будет только First, он делает это действительно имеет смысл бросить исключение, когда оно находится , экземпляр? Лично я не думаю, что это так; любая опасная операция, которую он делает, должна быть отложена до тех пор, пока вы не захотите ее вызвать, и , затем, хотите ли вы бросить свое исключение.

+0

Благодарим вас за внимание. Я добавляю только один 'enum' для уменьшения сложности. – hasanghaforian