Почему Java не позволяет универсальные подклассы Throwable?

Удаление Median DNS IP, изменение DNS-сервера клиента на ip-сервер решило проблему.

Клиент (windows 10): ip: 192.168.183.128 шлюз по умолчанию: 192.168.183.2 dns сервер: 192.168.183.132

142
задан Hosam Aly 1 February 2016 в 21:03
поделиться

3 ответа

Как сказанная метка, типы не reifiable, который является проблемой в следующем случае:

try {
   doSomeStuff();
} catch (SomeException<Integer> e) {
   // ignore that
} catch (SomeException<String> e) {
   crashAndBurn()
}

И SomeException<Integer> и SomeException<String> стираются к тому же типу, нет никакого пути к JVM для различения экземпляров исключения и поэтому никакого способа сказать, который catch должен быть выполнен блок.

149
ответ дан 23 November 2019 в 23:06
поделиться

Вот простой пример того, как использовать исключение:

class IntegerExceptionTest {
  public static void main(String[] args) {
    try {
      throw new IntegerException(42);
    } catch (IntegerException e) {
      assert e.getValue() == 42;
    }
  }
}

тело оператора TRy выдает исключение с данным значением, которое поймано пунктом выгоды.

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

class ParametricException<T> extends Exception {  // compile-time error
  private final T value;
  public ParametricException(T value) { this.value = value; }
  public T getValue() { return value; }
}

попытка скомпилировать вышеупомянутые отчеты ошибка:

% javac ParametricException.java
ParametricException.java:1: a generic class may not extend
java.lang.Throwable
class ParametricException<T> extends Exception {  // compile-time error
                                     ^
1 error

Это ограничение разумно, потому что почти любая попытка поймать такое исключение должна перестать работать, потому что тип не reifiable. Можно было бы ожидать, что типичное использование исключения будет чем-то как следующее:

class ParametricExceptionTest {
  public static void main(String[] args) {
    try {
      throw new ParametricException<Integer>(42);
    } catch (ParametricException<Integer> e) {  // compile-time error
      assert e.getValue()==42;
    }
  }
}

Это не разрешено, потому что тип в пункте выгоды не reifiable. Во время этой записи компилятор Sun сообщает о каскаде синтаксических ошибок в таком случае:

% javac ParametricExceptionTest.java
ParametricExceptionTest.java:5: <identifier> expected
    } catch (ParametricException<Integer> e) {
                                ^
ParametricExceptionTest.java:8: ')' expected
  }
  ^
ParametricExceptionTest.java:9: '}' expected
}
 ^
3 errors

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

14
ответ дан 23 November 2019 в 23:06
поделиться

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

try
{
    doSomethingThatCanThrow();
}
catch (MyException<Foo> e)
{
    // handle it
}

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

2
ответ дан 23 November 2019 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: