¿Es el vacío realmente insustanciable?


El javadoc para Void dice:

La clase Void es una clase de marcador de posición insustanciable para contener una referencia al objeto de Clase que representa la palabra clave Java void.

Pero el constructor es simplemente:

private Void() {}

Y este código crea una instancia de Void:

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

Así que Voides no insustanciable.

¿Habría habido una manera de hacer Void verdaderamente insustanciable?

Author: Roman C, 2012-12-27

3 answers

Hacer que su constructor sea privado, y no tener ningún otro constructor al que se pueda acceder desde fuera, hace que una clase no sea instanciable.

Sin embargo, no puede evitar que se acceda a ella usando Reflection API. Usando la reflexión, se puede hacer, lo que no está permitido normalmente.

Pero, si realmente quieres que tu clase sea insustanciable , incluso a través de Reflexión , puedes throw una Excepción sin marcar de la constructor.

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

En cuyo caso, cuando cree la instancia utilizando el método Constructor#newInstance(), lanzará un InvocationTargetException, como se cita en los comentarios de @ Alex.

Aquí está la documentación de Constructor#newInstance() el método, en la que se declara una lista de excepción, uno de ellos es InvocationTargetException, y dice que: -

Lanza:
InvocationTargetException-si el constructor subyacente lanza una excepción.

 28
Author: Rohit Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-27 20:10:41

Rohit tiene razón en que lanzar una excepción es "lo suficientemente bueno" para la mayoría de los casos de uso. Sin embargo, parece que podría ser posible evitar incluso eso, usando sun.misc.Inseguro:

Lanza Objetos nativos públicos allocateInstance(Clase cls) InstantiationException

Asignar una instancia pero no ejecutar ninguna constructor. Inicializa la clase si aún no lo ha sido.

(Tenga en cuenta que en realidad no he probado que esto funcione)

 29
Author: Steven Schlansker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-27 19:53:11

La API de Reflexión rompe todo tipo de "reglas" como esta, al igual que poder modificar los campos final. Hay muchas quejas sobre el hecho de que le permite romper las reglas duras y rápidas de Java, pero así es como es.

Sin Reflexión (o la loca API de @StevenSchlansker Unsafe publicada a continuación), no es posible crear instancias. Sin embargo, mientras se permita la reflexión, estas soluciones alternativas existirán.

En El propio tutorial de reflexión de Oracle , enumeran los beneficios e inconvenientes. Depende de ti decidir cuál es mayor.

También, ver esta pregunta: ¿Qué es la reflexión y por qué es útil?

 10
Author: asteri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:33:57