>
>
>
V6116. The class does not implement the…


V6116. The class does not implement the Closeable interface, but it contains the 'close' method that releases resources.

Анализатор обнаружил метод 'close', внутри которого происходит освобождение полей (ресурсов). Однако сам класс не реализует интерфейс 'Closeable' или 'AutoCloseable'.

Такой код может привести к следующим проблемам:

  • Без информации о реализованном интерфейсе другой разработчик может забыть вызвать метод 'close';
  • IoC-контейнеры, управляющие жизненным циклом объекта, не смогут вызвать метод 'close', когда объект станет не нужным. Это связано с тем, что контейнеры анализируют информацию о реализованных интерфейсах объекта.

Во всех описанных случаях ресурсы, удерживаемые объектом, не будут освобождены. Из-за этого может произойти нарушение логики работы программы. Например, если ресурс не будет освобождён, то из-за этого не получится получить доступ к нему из другой части кода.

Пример кода, который может привести к ошибкам:

сlass SomeClass {

  private FileWriter resource;
 
  public SomeClass(String name) {
    resource = new FileWriter(name); 
  }

  public void close() {
    resource.close();
  }
}

Исправленная версия класса 'SomeClass' будет выглядеть следующим образом:

сlass SomeClass implements Closeable {

  private FileWriter resource;
 
  public SomeClass(String name) {
    resource = new FileWriter(name); 
  }

  public void close() {
    resource.close();
  }
}

Может быть ситуация, когда сам класс реализует интерфейс или наследуется от класса, который уже содержит метод 'close':

interface SomeInterface {
  public void close(); 
}

class SomeInterfaceImpl implements SomeInterface {
  private FileWriter resource;
  
  public SomeInterfaceImpl(String name) {
    resource = new FileWriter(name); 
  }
  
  public void close() {
    resource.close(); 
  }
}

В таком случае имеется три решения. Первое связано с объявлением у класса с методом 'close' интерфейса 'Closeable' (или 'AutoCloseable'):

class SomeInterfaceImpl implements SomeInterface, Closeable {
  private FileWriter resource;
  
  public SomeInterfaceImpl(String name) {
    resource = new FileWriter(name); 
  }
  
  public void close() {
    resource.close(); 
  }
}

Второе решение связано с расширением интерфейса. В приведённом примере можно объявить у 'SomeInterface' родительский интерфейс 'Closeable' (или 'AutoCloseable'):

interface SomeInterface extends Closeable {
  public void close(); 
}

Если 'close' от 'SomeInterface' имеет реализации, в которых не происходит освобождение ресурсов, или наследовать 'Closeable' или 'AutoCloseable' по каким-то причинам нежелательно, тогда стоит переименовать данный метод, так как такое название характерно для этих интерфейсов:

interface SomeInterface {
  public void shut(); 
}