Подтвердить что ты не робот

Tricky try-catch java code

public class Strange1 {
  public static void main(String[] args) {
    try {
      Missing m = new Missing();
    } catch (java.lang.NoClassDefFoundError ex) {
      System.out.println("Got it!");
    }
  }
}

public class Strange2 {
  public static void main(String[] args) {
    Missing m;
    try {
      m = new Missing();
    } catch (java.lang.NoClassDefFoundError ex) {
      System.out.println("Got it!");
    }
  }
}

class Missing {
  Missing() { }
}

Если вы запустите Strange1 и Strange2 после удаления Missing.class, Strange1 будет бросать NoClassDefFoundError;, но Strange2 будет печатать Got it!

Кто-нибудь может это объяснить? Спасибо.

обновление:

java байт-код для Strange1:

     0  new info.liuxuan.test.Missing [16]
     3  dup
     4  invokespecial info.liuxuan.test.Missing() [18]
     7  astore_1 [m]
     8  goto 20
    11  astore_1 [ex]
    12  getstatic java.lang.System.out : java.io.PrintStream [19]
    15  ldc <String "Got it!"> [25]
    17  invokevirtual java.io.PrintStream.println(java.lang.String) : void [27]
    20  return
      Exception Table:
        [pc: 0, pc: 8] -> 11 when : java.lang.NoClassDefFoundError
      Line numbers:
        [pc: 0, line: 14]
        [pc: 11, line: 15]
        [pc: 12, line: 16]
        [pc: 20, line: 18]
      Local variable table:
        [pc: 0, pc: 21] local: args index: 0 type: java.lang.String[]
        [pc: 8, pc: 11] local: m index: 1 type: info.liuxuan.test.Missing
        [pc: 12, pc: 20] local: ex index: 1 type: java.lang.NoClassDefFoundError

java байт-код для Strange2:

     0  new info.liuxuan.test.Missing [16]
     3  dup
     4  invokespecial info.liuxuan.test.Missing() [18]
     7  astore_1 [m]
     8  goto 20
    11  astore_2 [ex]
    12  getstatic java.lang.System.out : java.io.PrintStream [19]
    15  ldc <String "Got it!"> [25]
    17  invokevirtual java.io.PrintStream.println(java.lang.String) : void [27]
    20  return
      Exception Table:
        [pc: 0, pc: 8] -> 11 when : java.lang.NoClassDefFoundError
      Line numbers:
        [pc: 0, line: 15]
        [pc: 11, line: 16]
        [pc: 12, line: 17]
        [pc: 20, line: 19]
      Local variable table:
        [pc: 0, pc: 21] local: args index: 0 type: java.lang.String[]
        [pc: 8, pc: 11] local: m index: 1 type: info.liuxuan.test.Missing
        [pc: 12, pc: 20] local: ex index: 2 type: java.lang.NoClassDefFoundError

Существует только одно место:

11  astore_1 [ex]

и

11  astore_2 [ex]

обновлено:

Каждый может попробовать это в затмении.

4b9b3361

Ответ 1

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

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

Ответ 2

Я создал два java файла. Strange1.java содержит классы Strange1 и Missing. Strange2.java содержит класс Strange2. Я удалил Missing.class. Я получил "Получил"! от обоих.

Пожалуйста, просмотрите следующие данные:

[email protected]:~$ java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) Server VM (build 20.0-b11, mixed mode)
[email protected]:~$ gedit Strange1.java
[email protected]:~$ gedit Strange2.java
[email protected]:~$ javac Strange1.java 
[email protected]:~$ javac Strange2.java 
[email protected]:~$ java Strange1
[email protected]:~$ java Strange2
[email protected]:~$ rm Missing.class
[email protected]:~$ java Strange1
Got it!
[email protected]:~$ java Strange2
Got it!

Я выполнил его в Linux-машине Ubuntu 11.04.

Так что это может быть версия java, которую вы используете.

Ответ 3

NoClassDefFoundError вызывается всякий раз, когда создается первая ссылка (объявляющая или создающая экземпляр) для отсутствующего класса. Теперь, бросая ошибку или ловя ее, зависит от того, используете ли вы блок try-catch для своей первой ссылки или нет.