Как восстановить поля-члены, которые уже были инициализированы, когда конструктор выдает ошибку - PullRequest
1 голос
/ 29 мая 2019
class XYZ {

   FileInputStream fis;  //opens a file stream
   DBConnection connection; //this is used to connect to a database

   XYZ(String fileName, String dbName) {
       fis = new FileInputStream(fileName);
       connection = getDBConnection(dbName); //assume that this line would throw error
   }
}

Рассмотрим следующий сценарий: объект класса XYZ создается как XYZ obj = new XYZ () - теперь во время создания объекта, когда вызывается конструктор, давайте предположим, что fis успешно инициализирован, но вызовемСледующее утверждение выдает ошибку.В отношении приведенного выше сценария:

  1. Содержит ли fis действительную ссылку?(поскольку оператор выполнен успешно, но следующий оператор не выполнен)

  2. Если fis содержит действительную ссылку, как убедиться, что fis будет закрыт, чтобы не было утечки памяти (Oneможно было бы определить метод finalize для этого класса, но Java GC не гарантирует, что будет вызван finalize ())

Ответы [ 2 ]

3 голосов
/ 29 мая 2019

Есть ли в справке действительная ссылка?(поскольку оператор выполнен успешно, но следующий оператор не выполнен)

Дело не в этом.Поле fis не существует после того, как конструктор «оставлен» из-за этого исключения.Но объект , на который ссылается fis, все еще существует.

Пока не начнет работать сборщик мусора. Когда GC удалит этот объект FileInputStream, он также вернет соответствующий файл.дескриптор базовой ОС (см. здесь для получения более подробной информации).

Реальная выгода здесь: вы не представляете, когда GC включится, чтобы вернуть файлсправиться.

Таким образом, вы можете либо сделать то, что предлагает ответ (чтобы сделать попытку перехватить второй вызов, и иметь fis.close() в блоке перехвата).Или вы рассматриваете другие способы решения этой проблемы, например, с помощью , а не , когда такие сложные операции выполняются в конструкторе объекта.

0 голосов
/ 29 мая 2019

Если создать соединение не удается, fis содержит действительную ссылку.
Вы можете попробовать следующее для решения этой проблемы:

class XYZ
{
  ...

  public XYZ(String fileName, String dbName)
    throws Exception
  {
    // Initialize attributes; not strictly necessary
    fis = null;
    connection = null;

    // Open fis
    fis = new FileInputStream(fileName);

    // Open connection
    try
    {
      connection = getDBConnection(dbName);
    }
    catch (Exception e)
    {
      fis.close();
      fis = null;
      throw e;
    }

  } // constructor

} // class XYZ
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...