2013-08-20 4 views
7

Опытного программистом новичок в Java ищет свою мудрость:Java метода с истекшим временем жизни объектов

Если нет никакого способа, чтобы гарантировать, что некоторые особенности фрагмента кода выполняются как объект выходит из области видимости, то, что существуют ли другие подходы, которые будут предлагать те же функциональные возможности? (кажется, окончательно явно не предназначены для этого)

Классическим примером является Scoped замок идиома:

void method() 
{ 
    // Thread-unsafe operations {...} 

    { // <- New scope 
     // Give a mutex to the lock 
     ScopedLock lock(m_mutex); 

     // thread safe operations {...} 

     if (...) return; // Mutex is unlocked automatically on return 

     // thread safe operations {...} 

    } // <- End of scope, Mutex is unlocked automatically 

    // Thread-unsafe operations {...} 
} 

Я могу понять, что в Java было бы неодобрительно, что какой-то код выполняется, если вам явно не назвали его. Но я считаю, что возможность принудительного исполнения какого-либо кода, который будет выполняться в конце жизни объекта, является очень мощной функцией, обеспечивающей разумное использование ваших классов клиентским кодом. Спасибо

+0

Согласитесь, это мощный. Я бы хотел, чтобы Java иногда использовала инструкцию 'C' 'using'. +1 Редактировать: У Guess Java есть это. см. ответ OldCurmudgeon. Если вы не используете Java 7, я бы пошел с попыткой/окончательным подходом к ошибкам. Хотя для блокировки нет автоматической обработки. –

ответ

1

Если вы хотите какой-то код будет работать в любом случае в методе, просто использовать попробовать ... наконец .... Окончательно блок гарантированно работать. Или, в Java 7, используется блок «с».

Если вы хотите, чтобы какой-то код запускался как деструктор C++. Я боюсь, что в Java нет такой вещи. Метод finalize не является надежным и не может использоваться для обработки критических миссий. Обычно классы Java обычно выставляют метод очистки (например, close() этих классов потоков), так что клиент явно вызывает эти методы для выполнения заданий очистки.

+0

Одна вещь, которую я иногда вижу, использует метод 'finalize', чтобы кричать на вас в ваших журналах, если объект не был очищен. На самом деле это не зависит от фактической очистки, но вы можете использовать ее для поиска ошибок, в которых вы не очищали. –

2

Начиная с Java 7 существует автоматическое управление ресурсами. Если ваша блокировка находится под вашим контролем, тогда сделайте ее реализацией AutoCloseable. К сожалению, блокировки java.util.concurrent не реализуют этот интерфейс. Here's a good reference.

9

Обычно - если вам нужно фактически закрыть/распорядиться ресурсами, то рекомендуется использовать структуру try{} finally{}.

// The old way - using try/finally 
    Statement stmt = con.createStatement(); 
    try { 
    ResultSet rs = stmt.executeQuery(query); 
    while (rs.next()) { 
     // ... 
    } 
    } catch (SQLException e) { 
    // Whatever ... . 
    } finally { 
    // Be sure to close the statement. 
    if (stmt != null) { 
     stmt.close(); 
    } 
    } 

Более поздние воплощения Java имеют интерфейс AutoCloseable, который можно использовать с механизмом with. Все Closeable Объекты автоматически AutoCloseable.

// Example of what is called try-with 
    try (Statement stmt = con.createStatement()) { 
    ResultSet rs = stmt.executeQuery(query); 
    while (rs.next()) { 
     // ... 
    } 
    } catch (SQLException e) { 
    // Whatever ... stmt will be closed. 
    } 
+0

+1, не знал, что это существовало. Поэтому я предполагаю, что Java теперь имеет эквивалент C# 'using'. –

+0

Форма try (resource), кажется, самая близкая вещь. Но для этого требуется, чтобы клиентский код поступал правильно. Но что, если внутренний ресурс внутри объекта Statement является деталью реализации, о которой пользователь не должен знать? Есть ли способ закрыть() для выполнения без явных мер, требуемых пользователем? – user1659313

+1

Нет, нет. Даже аргумент try-with-resource обсуждался для этой характеристики неочевидности, что противоречит духу Java, поэтому против интуиции опытного Java-программиста. –

1

Другой вариант замены finalize метод является PhantomReference. Если вы хотите выполнить какое-либо действие перед тем, как объект будет мусором, он предлагает другой хороший подход лучше, чем метод finalize.

Проверьте, например, здесь: https://weblogs.java.net/blog/kcpeppe/archive/2011/09/29/mysterious-phantom-reference

+0

Нет никакой гарантии, что объект будет собираться мусором. – jontro

+0

Цитата OP: «Кажется, финализация явно не предназначена для этого». И он прав. –

+0

Я могу понять, что с помощью метода finalize он не может быть гарантирован, но с помощью phantomreference также может не получить сбор мусора? – Lokesh

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