- Когда Java выдает ошибку ExceptionInInitializerError?
- 2. Ошибка ExceptionInInitializer
- 3. Статический блок инициализатора
- Когда Java выбрасывает ошибку ExceptionInInitializerError?
- 2. Ошибка exceptioninitializererror
- 3. Блок Статического Инициализатора
- 4. Инициализация статической Переменной
- 5. Проверенные исключения
- 5.1. OpenJDK
- 6. Заключение
- Русские Блоги
- Решение java.lang.ExceptionInInitializerError в тесте Junit
- Решение
Когда Java выдает ошибку ExceptionInInitializerError?
В этом кратком руководстве мы увидим, что заставляет Java создавать экземпляр исключения ExceptionInInitializerError .
Начнем с небольшого количества теории. Затем мы увидим несколько примеров этого исключения на практике.
2. Ошибка ExceptionInInitializer
ExceptionInInitializerError указывает , что в статическом инициализаторе возникло непредвиденное исключение . По сути, когда мы видим это исключение, мы должны знать, что Java не удалось оценить блок статического инициализатора или создать экземпляр статической переменной.
Фактически каждый раз, когда внутри статического инициализатора возникает какое-либо исключение, Java автоматически заключает это исключение в экземпляр класса ExceptionInInitializerError . Таким образом, он также поддерживает ссылку на фактическое исключение как на основную причину.
Теперь, когда мы знаем причину этого исключения, давайте посмотрим на это на практике.
3. Статический блок инициализатора
Чтобы инициализатор статического блока вышел из строя, мы намеренно разделим целое число на ноль:
public class StaticBlock private static int state; static state = 42 / 0; > >
Теперь, если мы вызовем инициализацию класса чем-то вроде:
Когда Java выбрасывает ошибку ExceptionInInitializerError?
В этом кратком руководстве мы увидим, что заставляет Java выбрасывать экземпляр ExceptionInInitializerError исключение.
Начнем с небольшой теории. Затем мы увидим несколько примеров этого исключения на практике.
2. Ошибка exceptioninitializererror
ExceptionInInitializerError указывает, что в статическом инициализаторе произошло непредвиденное исключение . В принципе, когда мы видим это исключение, мы должны знать, что Java не удалось вычислить статический блок инициализатора или создать экземпляр статической переменной.
Фактически, каждый раз, когда какое-либо исключение происходит внутри статического инициализатора, Java автоматически обертывает это исключение внутри экземпляра класса ExceptionInInitializerError . Таким образом, он также поддерживает ссылку на фактическое исключение в качестве основной причины.
Теперь, когда мы знаем причину этого исключения, давайте рассмотрим его на практике.
3. Блок Статического Инициализатора
Чтобы иметь неудачный инициализатор статического блока, мы намеренно разделим целое число на ноль:
Теперь, если мы инициализируем инициализацию класса с помощью чего-то вроде:
Тогда мы увидим следующее исключение:
java.lang.ExceptionInInitializerError at com.baeldung. (ExceptionInInitializerErrorUnitTest.java:18) Caused by: java.lang.ArithmeticException: / by zero at com.baeldung.StaticBlock.(ExceptionInInitializerErrorUnitTest.java:35) . 23 more
Как упоминалось ранее, Java создает исключение ExceptionInInitializerError , сохраняя при этом ссылку на первопричину:
assertThatThrownBy(StaticBlock::new) .isInstanceOf(ExceptionInInitializerError.class) .hasCauseInstanceOf(ArithmeticException.class);
Также стоит упомянуть, что метод является методом инициализации класса в JVM.
4. Инициализация статической Переменной
То же самое происходит, если Java не инициализирует статическую переменную:
Опять же, если мы запустим процесс инициализации класса:
Затем происходит то же самое исключение:
java.lang.ExceptionInInitializerError at com.baeldung. (ExceptionInInitializerErrorUnitTest.java:11) Caused by: java.lang.RuntimeException at com.baeldung.StaticVar.initializeState(ExceptionInInitializerErrorUnitTest.java:26) at com.baeldung.StaticVar.(ExceptionInInitializerErrorUnitTest.java:23) . 23 more
Аналогично статическим блокам инициализатора, первопричина исключения также сохраняется:
assertThatThrownBy(StaticVar::new) .isInstanceOf(ExceptionInInitializerError.class) .hasCauseInstanceOf(RuntimeException.class);
5. Проверенные исключения
В рамках спецификации языка Java (JLS-11.2.3) мы не можем выбрасывать проверенные исключения внутри блока статического инициализатора или инициализатора статической переменной. Например, если мы попытаемся сделать это:
Компилятор потерпит неудачу со следующей ошибкой компиляции:
java: initializer must be able to complete normally
В качестве соглашения мы должны обернуть возможные проверенные исключения внутри экземпляра Исключение ininitializererror когда наша статическая логика инициализации выдает проверенное исключение:
public class CheckedConvention < private static Constructorconstructor; static < try < constructor = CheckedConvention.class.getDeclaredConstructor(); >catch (NoSuchMethodException e) < throw new ExceptionInInitializerError(e); >> >
Как показано выше, метод getDeclaredConstructor() вызывает проверенное исключение. Поэтому мы поймали проверенное исключение и завернули его, как предполагает конвенция.
Поскольку мы уже возвращаем экземпляр Исключение ininitializererror исключение явно, Java не будет заключать это исключение в еще одно Исключение ininitializererror пример.
Однако, если мы создадим любое другое непроверенное исключение, Java выдаст другое ExceptionInInitializerError :
static < try < constructor = CheckedConvention.class.getConstructor(); >catch (NoSuchMethodException e) < throw new RuntimeException(e); >>
Здесь мы заключаем проверенное исключение в непроверенное. Поскольку это непроверенное исключение не является экземпляром ExceptionInInitializerError, Java снова обернет его, что приведет к этой неожиданной трассировке стека:
java.lang.ExceptionInInitializerError at com.baeldung.exceptionininitializererror. Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: . Caused by: java.lang.NoSuchMethodException: com.baeldung.CheckedConvention.() at java.base/java.lang.Class.getConstructor0(Class.java:3427) at java.base/java.lang.Class.getConstructor(Class.java:2165)
Как показано выше, если мы будем следовать соглашению, то трассировка стека будет намного чище, чем это.
5.1. OpenJDK
В последнее время это соглашение даже используется в самом исходном коде OpenJDK. Например, вот как AtomicReference использует этот подход:
public class AtomicReferenceimplements java.io.Serializable < private static final VarHandle VALUE; static < try < MethodHandles.Lookup l = MethodHandles.lookup(); VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class); >catch (ReflectiveOperationException e) < throw new ExceptionInInitializerError(e); >> private volatile V value; // omitted >
6. Заключение
В этом уроке мы увидели, что заставляет Java выбрасывать экземпляр ExceptionInInitializerError exception.
Как обычно, все примеры доступны на GitHub .
Русские Блоги
Решение java.lang.ExceptionInInitializerError в тесте Junit
Этот метод может быть лишь одной из сцен. Если вы столкнетесь с ним, вам следует записать его, чтобы вы могли быстро проверить, когда столкнетесь с ним снова.
java.lang.ExceptionInInitializerError at io.reactivex.android.schedulers.AndroidSchedulers$1.call(AndroidSchedulers.java:35) at io.reactivex.android.schedulers.AndroidSchedulers$1.call(AndroidSchedulers.java:33) at io.reactivex.android.plugins.RxAndroidPlugins.callRequireNonNull(RxAndroidPlugins.java:70) at io.reactivex.android.plugins.RxAndroidPlugins.initMainThreadScheduler(RxAndroidPlugins.java:40) at io.reactivex.android.schedulers.AndroidSchedulers.(AndroidSchedulers.java:32) at com.teambition.account.signin.SignInViewModel.loginWithEmail(SignInViewModel.kt:49) at com.teambition.account.signin.SignInViewModelTest.loginWithEmail(SignInViewModelTest.kt:53) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:389) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:114) at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.lambda$invokeTestMethod$6(MethodTestDescriptor.java:167) at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40) at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.invokeTestMethod(MethodTestDescriptor.java:163) at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.execute(MethodTestDescriptor.java:110) at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.execute(MethodTestDescriptor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:83) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Iterator.forEachRemaining(Iterator.java:116) at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Iterator.forEachRemaining(Iterator.java:116) at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:62) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131) Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details. at android.os.Looper.getMainLooper(Looper.java) at io.reactivex.android.schedulers.AndroidSchedulers$MainHolder.(AndroidSchedulers.java:29) . 63 more
Решение
Добавить команду скрипта в gradle