Могут ли блоки статического кода генерировать исключения?

В гипотетической ситуации у меня есть такой класс:

import java.io.File;
import java.util.Scanner;
class X
{
    static Scanner scanner;
    static
    {
        scanner = new Scanner(new File("X.txt"));
    }
}

При компиляции получаю

незарегистрированное исключение java.io.FileNotFoundException; должен быть пойман или объявлен брошенным

потому что public Scanner(File source) throws FileNotFoundException.

Чтобы исправить это, я могу поместить scanner = new... строку в оператор try/catch:

    static
    {
        try
        {
            scanner = new Scanner(new File("X.txt"));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

Однако есть ли способ сделать что-то вроде:

    static throws java.io.FileNotFoundException
    {
        scanner = new Scanner(new File("X.txt"));
    }

Это гипотетическая ситуация. Пожалуйста, не говорите: «Ну, зачем тебе это?» или "Вот лучший способ сделать Сканер!"


person The Guy with The Hat    schedule 24.01.2014    source источник
comment
Честно говоря, я не вижу здесь проблемы.   -  person Josh M    schedule 24.01.2014


Ответы (2)


Из JLS §11.2.3 :

Это ошибка времени компиляции, если инициализатор переменной класса (§8.3.2) или статический инициализатор (§8.7) именованного класса или интерфейса может вызвать проверенный класс исключения.

Для полноты картины непроверенное исключение определено в JLS §11.1.1:

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

Непроверенные классы исключений — это классы исключений времени выполнения и классы ошибок.

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

person arshajii    schedule 24.01.2014

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

Однако исключение, которое вы, наконец, получите, будет некоторой формой ClassInitializationException, и вы можете изучить вложенные исключения, чтобы определить основную причину.

person Bhaskar    schedule 24.01.2014
comment
Не могли бы вы добавить пример кода для этого? - person MasterJoe; 05.07.2019
comment
Какой-то ClassInitializationException на самом деле является Error, и его нельзя восстановить. Так что бросать непроверенное исключение — это действительно плохая идея. - person Stephen C; 06.07.2019