2015-06-06 2 views
3

У меня есть код, который создает JarFile и URLClassLoader, оба из которых я хочу закрыть в конце. Естественно, я решил использовать finally блок, чтобы иметь дело с очисткой:Работа с блоком finally

JarFile jar = ...; 
URLClassLoader loader = ...; 
try { 
    // work ... 
} finally { 
    jar.close(); 
    loader.close(); 
} 

Однако оба close() вызовов могут выбросить исключение, так что если jar.close() будет сгенерировано исключение, то loader.close() не будет достигнут. Один из способов я думал о работе вокруг этого окружив jar.close() с примеркой поймать блок:

JarFile jar = ...; 
URLClassLoader loader = ...; 
try { 
    // work ... 
} finally { 
    try { 
     jar.close(); 
    } catch(IOException e) { 
    } 
    loader.close(); 
} 

Но это кажется уродливым и чрезмерными. Есть ли элегантный способ справиться с исключениями, связанными с очисткой, в блоках finally?

+0

ты не должен закрывать позиции в обратном порядке? –

ответ

6

В Java 7 и последующих версиях есть попытка с ресурсами, которые обрабатывают Closeable объектов.

переформатировать код Thusly,

try(JarFile jar = ....; URLClassLoader loader = ....;) 
{ 
    // work ... 
} 

только классы, которые реализуют интерфейс Closeable будет работать таким образом, оба этих класса отвечают этим критериям.

+0

Ницца приятно, я склонен пропустить эти «новые» функции. Похоже, что я буду реорганизовывать некоторый код в активном проекте :) – MalaKa

+0

Да, мне очень понравилась эта функция, я всегда использовал метод 'closeQuietly (Closeable ... closeable)', чтобы выполнить то же самое, что и ответ Дици, но разрешил одиночный вызов до. –

2

Конечно, есть способ инкапсулировать это, это называется методом! Например, вы можете создать класс IOUtils как:

public class IOUtils { 
    // this class is not meant to be instantiated 
    private IOUtils() { } 

    public static void closeQuietly(Closeable c) {  
     if (c == null) return; 
     try { 
      c.close(); 
     } catch (IOException e) { } 
    } 
} 

И потом,

JarFile jar = ...; 
URLClassLoader loader = ...; 
try { 
    // work ... 
} finally { 
    closeQuietly(jar); 
    loader.close(); 
} 

Как Patrick J ABAE II сказал, вы можете также использовать Try-улов с ресурсов , но вы не всегда можете это сделать, например, если вы сначала создаете InputStream в try-catch, а затем создаете несколько разных типов InputStream, инкапсулируя первый (например: инкапсулируйте в CipherInputStream, чтобы расшифровать данные, а затем напишите FileOutputStream). Тем не менее, я не говорю, что попытка try-catch с ресурсами не является полезной конструкцией, этого достаточно в большинстве случаев.

+0

Как вы используете этот класс? –

+0

@ LutzHorn Что значит? Он предназначен для использования в качестве любого утилитарного класса с помощью статических методов. – Dici

+0

Ну, теперь, когда вы отредактировали свой ответ, он становится яснее. –

2

Использование try-with-resources:

try (JarFile jar = new JarFile(filename); 
      URLClassLoader loader = URLClassLoader.newInstance(urls)) { 
     // do stuff 
    } catch (IOException ex) { 
     // handle ex   
    } 
Смежные вопросы