Неужели Пустота действительно не нужна?

javadoc для Void говорит:

Класс Void является неинтересным классом-заполнителем для ссылки на объект класса, представляющий ключевое слово void.

но конструктор просто:

private Void() {}

и этот код создает экземпляр Void:

Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
Void v = c.newInstance(); // Hello sailor

Итак, Void не является необратимым.

Был ли способ сделать Void действительно неинстанционным?

Ответ 1

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

Однако вы не можете избежать доступа к нему с помощью Reflection API. Используя отражение, вы можете сделать то, что не разрешено нормально.

Но если вы действительно хотите, чтобы ваш класс был неинтуитивным, даже через Reflection, вы можете throw удалить неконтролируемое исключение из конструктора.

private MyClass() {
    throw UnsupportedOperationException("Can't instantiate class");
}

В этом случае при создании экземпляра с использованием метода Constructor#newInstance() он выкинет InvocationTargetException, как указано в комментариях @Alex.

Здесь документация метода Constructor#newInstance(), в котором объявляется список исключений, один из которых InvocationTargetException, и он говорит, что: -

throws:
InvocationTargetException - если базовый конструктор выдает исключение.

Ответ 2

Rohit совершенно прав, что исключение является "достаточно хорошим" для большинства случаев использования. Тем не менее, похоже, что возможно обходить даже это, используя sun.misc.Unsafe:

public native Object allocateInstance (класс cls) бросает Исключение моментации

Выделить экземпляр, но не запускать конструктор. Инициализирует класс, если он еще не был.

(Заметим, что я действительно не проверял, что это работает)

Ответ 3

API Reflection разбивает всевозможные "правила", подобные этому, так же как возможность изменять поля final. Есть много жалоб на то, что он позволяет вам нарушать жесткие и быстрые правила Java, но это как.

Без Reflection (или @StevenSchlansker crazy Unsafe API, опубликованный ниже), невозможно создать экземпляр. Тем не менее, если разрешить отражение, эти обходные пути будут существовать.

В собственный инструмент Reflection от Oracle, они перечисляют преимущества и недостатки. Вам решать, что больше.

Также см. этот вопрос: Что такое отражение и почему оно полезно?