Могут ли конструкторы исключать исключения из Java?

Разрешены ли конструкторы для исключения исключений?

Ответ 1

Да, конструкторы могут генерировать исключения. Обычно это означает, что новый объект сразу же подходит для сбора мусора (хотя его, возможно, не собирают в течение некоторого времени, конечно). Возможно, что "полуконструированный" объект будет придерживаться, хотя он сделал себя видимым ранее в конструкторе (например, назначив статическое поле или добавив себя в коллекцию).

Остерегайтесь бросать исключения в конструкторе: поскольку вызывающий (обычно) не сможет использовать новый объект, конструктор должен быть осторожным, чтобы избежать получения неуправляемых ресурсов (дескрипторы файлов и т.д.), а затем бросая исключение, не отпуская их. Например, если конструктор пытается открыть FileInputStream и a FileOutputStream, а первый - неудачно, но второй не удастся, вы должны попытаться закрыть первый поток. Это становится сложнее, если это конструктор подкласса, который генерирует исключение, конечно... все становится немного сложнее. Это не проблема очень часто, но это стоит рассмотреть.

Ответ 2

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

Ниже приведено Правила безопасного кодирования 2.0.

Частично инициализированные экземпляры не конечного класса могут быть доступны через атаку финализатора. Атакующий переопределяет защищенный метод finalize в подклассе и пытается создать новый экземпляр этого подкласса. Эта попытка не выполняется (в приведенном выше примере проверка SecurityManager в конструкторе ClassLoader вызывает исключение безопасности), но злоумышленник просто игнорирует любое исключение и ожидает, что виртуальная машина выполнит финализацию на частично инициализированном объекте. Когда это происходит, вызывается реализация метода злонамеренного финализа, предоставляющая злоумышленнику доступ к этому, ссылка на завершаемый объект. Хотя объект только частично инициализирован, злоумышленник все равно может вызывать методы на нем (тем самым обходя проверку SecurityManager).

Ответ 3

Совершенно верно.

Если конструктор не получает действительного ввода или не может построить объект в допустимом порядке, у него нет другой опции, кроме как выдать исключение и предупредить его вызывающего.

Ответ 4

Да, конструкторам разрешено создавать исключения.

Однако будьте очень мудрыми в выборе того, какие исключения они должны быть - проверенные исключения или непроверенные. Исключенные исключения - это в основном подклассы RuntimeException.

Почти во всех случаях (я не мог придумать исключения для этого случая), вам нужно выбросить проверенное исключение. Причина состоит в том, что исключенные исключения (например, NullPointerException) обычно вызваны ошибками программирования (например, недостаточно проверять входные данные).

Преимущество, которое предлагает проверенное исключение, заключается в том, что программист вынужден поймать исключение в своем коде инстанцирования и тем самым понимает, что может возникнуть сбой при создании экземпляра объекта. Конечно, только обзор кода поймает плохую практику программирования проглатывания исключения.

Ответ 5

Да, это может вызвать исключение, и вы можете объявить это в сигнатуре конструктора тоже, как показано в примере ниже:

public class ConstructorTest
{
    public ConstructorTest() throws InterruptedException
    {
        System.out.println("Preparing object....");
        Thread.sleep(1000);
        System.out.println("Object ready");
    }

    public static void main(String ... args)
    {
        try
        {
            ConstructorTest test = new ConstructorTest();
        }
        catch (InterruptedException e)
        {
            System.out.println("Got interrupted...");
        }
    }
}

Ответ 6

Да.

Конструкторы - это не что иное, как специальные методы, и могут генерировать исключения, как любой другой метод.

Ответ 7

Конструктор CAN может вызывать любое исключение. Но если какой-либо конструктор подкласса вызывает конструктор суперкласса, который генерирует исключение, то конструктор подкласса должен либо поймать исключение, либо выбросить его.

Ответ 8

public class Stack {


class SizeOutOfBounds extends Exception{
    private static final long serialVersionUID = 1L;

    public SizeOutOfBounds(String value){
        super(value);
    }
}

private static final int DEFAULT_SIZE = 10;
int[] stack;

//another example where constructor can throw exception..
public Stack(int size) throws SizeOutOfBounds{
    if(size <= 0){
        throw new SizeOutOfBounds(String.valueOf(size));
    }
    stack = new int[size];
}

public Stack() throws SizeOutOfBounds{
    this(DEFAULT_SIZE);
}

/**
 * 
 */

}