реализует Closeable или реализует AutoCloseable

м в процессе изучения Java, и я не могу найти хорошего объяснения наimplements Closeable иimplements AutoCloseable интерфейсы.

Когда я реализовалinterface Closeable, моя Eclipse IDE создала метод.public void close() throws IOException

Я могу закрыть поток, используяpw.close(); без интерфейса. Но я не могу понять, как я могу реализоватьclose() метод с использованием интерфейса. И какова цель этого интерфейса?

Также я хотел бы знать: как я могу проверить, еслиIOstream был действительно закрыт?

Я использовал основной код ниже

import java.io.*;

public class IOtest implements AutoCloseable {

public static void main(String[] args) throws IOException  {

    File file = new File("C:\\test.txt");
    PrintWriter pw = new PrintWriter(file);

    System.out.println("file has been created");

    pw.println("file has been created");

}

@Override
public void close() throws IOException {


}
 crusam30 окт. 2012 г., 15:51
Я думаю, что все уже сказано, но, возможно, вас заинтересовала следующая статья о попытках использования ресурсов:docs.oracle.com/javase/tutorial/essential/exceptions/... , Это также может быть полезно для понимания данных ответов.

Ответы на вопрос(6)

Вот маленький пример

public class TryWithResource {

    public static void main(String[] args) {
        try (TestMe r = new TestMe()) {
            r.generalTest();
        } catch(Exception e) {
            System.out.println("From Exception Block");
        } finally {
            System.out.println("From Final Block");
        }
    }
}



public class TestMe implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println(" From Close -  AutoCloseable  ");
    }

    public void generalTest() {
        System.out.println(" GeneralTest ");
    }
}

Вот вывод:

GeneralTest 
From Close -  AutoCloseable  
From Final Block
 raxetul03 янв. 2019 г., 09:50
Лучше написать вывод также, чтобы не было необходимости в пробном проекте для такого короткого кода.

AutoCloseable (представлен в Java 7) позволяет использовать идиому try-with-resources:


    public void close() throws Exception {
        System.out.println("Closing!");
    }

}

Теперь вы можете сказать:

try(MyResource res = new MyResource()) {
    //use res here
}

и JVM позвонитclose() автоматически для вас.Closeable это старый интерфейс.По какой-то причине Для сохранения языка обратной совместимости дизайнеры решили создать отдельный. Таким образом, не только всеCloseable классы (например, бросание потоковIOException) может использоваться в try-with-resources, но также и в тех, которые хотят генерировать более общее проверенное исключение из.close()

Если есть сомнения, используйтеAutoCloseableпользователи вашего класса будут благодарны.

 Tomasz Nurkiewicz30 окт. 2012 г., 15:57
@MarkRotteveel: +1, спасибо. Я исправил свой ответ, чтобы отразить ваши предложения и комментарии.
 xdhmoore16 июл. 2015 г., 00:33
Closeable негарантия идемпотентность. Этотребует идемпотентность у пользователяс реализациейclose() метод. И будьIOException Более конкретный / соответствующий зависит от варианта использования. "
 Andrew McKinlay20 апр. 2015 г., 02:11
Если есть сомнения, используйтеAutoCloseableпользователи вашего класса будут благодарны. Wouldn»пользователи предпочитаютCloseable, так как это гарантирует идемпотентность и выбрасывает более конкретное IOException?
 MondKin18 янв. 2018 г., 04:50
Вы также можете использовать Closable в попытке с ресурсами, так как Closable является подинтерфейсом AutoClosable
 Mikkel Løkke20 февр. 2015 г., 12:46
За исключением того, что это нарушает обратную совместимость, потому что вещи, которые раньше были Closable (например,javax.sql.Connection) есть сейчастолько AutoClosable, так выигралбольше не работаю с библиотеками (например, commons-io), потому что они поддерживают только Closable (потому что им нужно компилировать не с Java 7 JDK). "
 Lukas Eder25 янв. 2014 г., 18:00
А также:Closeable.close() требуется быть идемпотентом.AutoCloseable.close() нет, хотя это все еще настоятельно рекомендуется.
 Mark Rotteveel30 окт. 2012 г., 15:49
Причина проста:Closeable.close() бросаетIOException, Многоclose() методы, которые могут извлечь выгоду из try-with-resources, выдают другие проверенные исключения (например,java.sql.Connection.close() такAutoCloseable.close() бросаетException, Изменение существующегоCloseable контракт нарушит все существующие приложения / библиотеки, полагаясь на контракт, которыйclose() только броскиIOException и не все (проверенные) исключения.
 gerardw15 нояб. 2014 г., 21:23
Кроме того, нет использовать по умолчаниюpublic void close( ) throws Exception - используйте более конкретное исключение, если можете (например, IOException)
 Vadzim28 июл. 2015 г., 16:14
Если вы сомневаетесь, используйте AutoCloseable, пользователи вашего класса будут благодарны " - это делаешьне дает никакой выгоды, так как старшеClosable был модернизирован для реализацииAutoCloseable тоже.

Я нашел кое-что о разнице между AutoCloseable и Closeable.

Интерфейс AutoCloseable был представлен в Java 7. До этого существовал другой интерфейс под названием Closeable. Это было похоже на то, что хотели дизайнеры языка, за следующими исключениями:

Closeable ограничивает тип исключения, генерируемый IOException.Закрываемый требует, чтобы реализации были идемпотентными.

Разработчики языка подчеркивают обратную совместимость. Поскольку изменение существующего интерфейса было нежелательным, они создали новый интерфейс, который называется AutoCloseable. Этот новый интерфейс менее строг, чем Closeable. Поскольку Closeable соответствует требованиям для AutoCloseable, он начал внедрять AutoCloseable, когда последний был представлен.

Решение Вопроса

что вы не очень знакомы с интерфейсами. В коде, который вы разместили, вы нет нужно реализовать.AutoCloseable

Вы должны будете только (или должны) реализоватьCloseable или жеAutoCloseable если вы собираетесь реализовать свой собственныйPrintWriter который обрабатывает файлы или любые другие ресурсы, которые должны быть закрыты.

В вашей реализации достаточно позвонитьpw.close(), Вы должны сделать это в блоке finally:

PrintWriter pw = null;
try {
   File file = new File("C:\\test.txt");
   pw = new PrintWriter(file);
} catch (IOException e) {
   System.out.println("bad things happen");
} finally {
   if (pw != null) {
      try {
         pw.close();
      } catch (IOException e) {
      }
   }
}

Код выше относится к Java 6. В Java 7 это можно сделать более элегантно (см.этот ответ).

 Kai26 янв. 2015 г., 20:48
Вы абсолютно правы. Вопрос был оPrintWriter поэтому я упомянул это, чтобы быть более конкретным.
 Josh07 дек. 2015 г., 16:06
Это так громоздко, но это работает.
 glglgl26 янв. 2015 г., 15:53
Почему только сPrintWriter? ОсобенноAutoClosable объекты могут быть использованы в гораздо большем количестве случаев, чем простоPrintWriters ...
 ᴠɪɴᴄᴇɴᴛ01 дек. 2017 г., 15:09
Зачем описывать ситуацию для Java 6 в контекстеAutoCloseable? Лучше покажиtry-with-resources вместо ...

try-with-resources Утверждение.

try-with-resources statement этоtry заявление, которое объявляет один или несколько ресурсов.resource является объектом, который должен быть закрыт после завершения программыtry-with-resources statement гарантирует, что каждый ресурс закрыт в конце оператора. Любой объект, который реализуетjava.lang.AutoCloseable, который включает в себя все объекты, которые реализуютjava.io.Closeable, может быть использован в качестве ресурса.

Следующий пример читает первую строку из файла. Он использует экземплярBufferedReader читать данные из файла.BufferedReader ресурс, который должен быть закрыт после завершения программы:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

В этом примере ресурс, объявленный в операторе try-with-resources, является BufferedReader. Оператор объявления появляется в скобках сразу после ключевого слова try. КлассBufferedReaderв Java SE 7 и более поздних версиях реализует интерфейсjava.lang.AutoCloseable, ПосколькуBufferedReader экземпляр объявляется в операторе try-with-resource, он будет закрыт независимо от того, завершается ли оператор try нормально или внезапно (в результате методаBufferedReader.readLine бросатьIOException).

До Java SE 7 вы можете использоватьfinally блок, чтобы гарантировать, что ресурс закрыт независимо от того, завершается ли оператор try нормально или внезапно. В следующем примере используетсяfinally блок вместоtry-with-resources заявление:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }

}

пожалуйстаобратитесь к документации.

Closeable продолжаетсяAutoCloseableи специально предназначен для потоков ввода-вывода: он генерирует IOException вместо Exception и является идемпотентом, тогда как AutoCloseable не 'не предоставляем эту гарантию.

Это все объясняется в javadoc обоих интерфейсов.

Реализация AutoCloseable (или Closeable) позволяет использовать класс в качестве ресурса конструкции try-with-resources, представленной в Java 7, что позволяет автоматически закрывать такие ресурсы в конце блока, не добавляя блок finally, который закрывает ресурс явно.

Ваш класс нет представляет собой закрытый ресурс, и тамНет абсолютно никакого смысла в реализации этого интерфейса: IOTest можетбыть закрытым Это не должнодаже невозможно создать его экземпляр, так как он неУ меня нет метода экземпляра. Помните, что реализация интерфейса означает, что естьэто отношения между классом и интерфейсом. У вас нет таких отношений здесь.

 lospejos13 июл. 2016 г., 17:13
Просто реализоватьПерекрываемый для связанных с потоками классов, иAutoClosable для других, для которых требуется функция автозаполнения.

Ваш ответ на вопрос