2014-03-23 2 views
1

Мне любопытно инициализация полей, которые выдают проверенные исключения. Например,Как уловить CheckedException, вызванное во время инициализации поля?

public static final FileOutputStream fileOut1 = new FileOutputStream(new File("test.txt")); 

Это дает ошибку компиляции «Необработанный тип исключения FileNotFoundException». Я знаю, что могу использовать статические блоки инициализатора, как показано ниже, но есть ли более элегантные способы?

public static final FileOutputStream fileOut2; 
static { 
    FileOutputStream temp = null; 
    try { 
     temp = new FileOutputStream(new File("test.txt")); 
    } catch (FileNotFoundException e) { 
     //log some warnings, maybe 
    }finally{ 
     fileOut2= temp; 
    } 
} 

Как насчет нестатические поля экземпляра

public final FileOutputStream fileOut3 = new FileOutputStream(new File("test.txt")); 

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

public final FileOutputStream fileOut3 = new FileOutputStream(new File("test.txt")); 
public MyClassFoo(){ 
    try{ 
     super();//compile error 
    }catch(Exception e){ 

    } 
} 

Ошибка компиляция уходит, если я бросаю FileNotFoundException, но есть способ, чтобы перехватывать исключения выписок инициализации, не прибегая к Initializer блоков или принести заявления в самих конструкторах?

public MyClassFoo() throws FileNotFoundException{ 

} 

ответ

3

Относительно статических полей. Первое, что я хотел бы сделать, это не открывать поток файлов при инициализации класса. Это действительно должно быть сделано внутри метода. И он должен убедиться, что поток закрыт. Тем не менее, вы можете избежать статического блока, делегируя методу:

private static final FileOutputStream fileOut1 = openFileStream(); 

Метод будет иметь дело с исключением.

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

+0

Отлично, спасибо. Следующий вопрос. Исключения, сброшенные (отмеченные или не отмеченные) полями, повторно создаются конструктором, поэтому клиенты должны улавливать при вызове конструкторов. Есть ли способ перехватить их, не отпуская их на клиентский код? – hummingV

+0

Err, да, поймав их. Инициализируйте поля с помощью метода или конструктора и поймайте исключение в методе или конструкторе. Но зачем вам это нужно? Вероятно, ваш объект не сможет ничего сделать, если его поля не были инициализированы должным образом. Исключения - хорошая вещь: они сигнализируют об ошибках. Улавливание исключения только скроет ошибку и вызовет другие, более трудные для диагностики. –

Смежные вопросы