java packages java.lang

¿Por qué puedo volver a crear el paquete y las clases java.lang?



packages (4)

Solo estoy jugando con la estructura del paquete. Y para mi sorpresa, puedo omitir las clases predeterminadas al crear mi paquete y el nombre de clase con ese nombre.

Por ejemplo:

Creé un paquete llamado java.lang y Class es Boolean . Cuando importo java.lang.Boolean , no es la versión de JDK de Boolean . Es mio. Solo muestra los métodos de Objects que tiene cada objeto Java.

Porque ? ¿Por qué puedo crear el paquete java.lang ? Y el programa funciona bien.

Otro baffle es si creo una Class con el nombre Object y trato de ejecutar el programa, entonces una excepción

java.lang.SecurityException: Prohibited package name: java.lang at java.lang.ClassLoader.preDefineClass(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source)

¿Por qué es este comportamiento? ¿Es esto un error o un comportamiento normal?


La restricción en las clases java.lang es una restricción de tiempo de ejecución, no de compilación.

La JVM proporciona específicamente un mecanismo para anular las clases en java.lang . Puedes hacerlo usando el -Xbootclasspath línea de comando -Xbootclasspath :

-Xbootclasspath:bootclasspath
Especifica una lista de directorios, archivos JAR y archivos ZIP separados por punto y coma para buscar archivos de clases de arranque. Estos se utilizan en lugar de los archivos de clases de arranque incluidos en la plataforma Java JDK.

Las aplicaciones que usan esta opción para reemplazar una clase en rt.jar no deben desplegarse porque hacerlo contravendría la licencia de código binario de Java Runtime Environment.

-Xbootclasspath/a:path
Especifica una ruta de directorios, archivos JAR y archivos ZIP separados por punto y coma para agregar a la ruta predeterminada de la clase de arranque.

-Xbootclasspath/p:path
Especifica una ruta de directorios, archivos JAR y archivos ZIP separados por punto y coma para agregar al frente de la ruta predeterminada de la clase de arranque.

No implemente aplicaciones que usen esta opción para anular una clase en rt.jar porque esto viola la licencia del código binario de Java Runtime Environment.

Sin embargo, como ya he destacado con las marcas en negrita, hacerlo es una violación del Acuerdo de Licencia del Código Binario de Oracle para Java SE y JavaFX Technologies :

D. RESTRICCIONES DE LA TECNOLOGÍA DE JAVA. No puede crear, modificar o cambiar el comportamiento de, o autorizar a sus licenciatarios para crear, modificar o cambiar el comportamiento de clases, interfaces o subpaquetes que de alguna manera están identificados como "java", "javax", " javafx "," sun "," oracle " o convención similar especificada por Oracle en cualquier designación de convención de nomenclatura. No deberá redistribuir el Software listado en el Anexo 1.

Además de lo anterior, puede agregar cualquier clase que desee a los paquetes que desee ; se trata específicamente en el JLS §13.3 :

13.3. Evolución de los paquetes

Se puede agregar una nueva clase de nivel superior o tipo de interfaz a un paquete sin romper la compatibilidad con los binarios preexistentes, siempre que el nuevo tipo no reutilice un nombre previamente dado a un tipo no relacionado.

Si un nuevo tipo reutiliza un nombre dado previamente a un tipo no relacionado, entonces puede surgir un conflicto, ya que los binarios para ambos tipos no pueden ser cargados por el mismo cargador de clases.

Los cambios en la clase de nivel superior y los tipos de interfaz que no son públicos y que no son una superclase o superinterfaz, respectivamente, de un tipo público, afectan solo a los tipos dentro del paquete en el que se declaran. Dichos tipos pueden eliminarse o modificarse de otra forma, incluso si las incompatibilidades se describen de otra manera aquí, siempre que los binarios afectados de ese paquete se actualicen juntos.


Respuesta a SecurityException pregunta relacionada con SecurityException :

SecurityManger lanza esta RuntimeException mientras que el cargador de clases que llama defineClass método defineClass y encontró el nombre de la clase especificada (su "clase personalizada") tiene "java. *".

Esto se debe a que definió su clase en el paquete "java. *" Y, según la documentación de ClassLoader, esto no está permitido.

defineClass ()

..

El nombre especificado no puede comenzar con "java.", Ya que todas las clases en los paquetes "java. * Solo pueden ser definidas por el cargador de clases bootstrap. Si el nombre no es nulo, debe ser igual al nombre binario de la clase especificada por la matriz de bytes "b"; de lo contrario, se lanzará NoClassDefFoundError.

Lanza: ..

SecurityException: si se intenta agregar esta clase a un paquete que contiene clases firmadas por un conjunto diferente de certificados que esta clase, o si el nombre comienza con "java".

Para su prueba, intente crear el paquete java.test y defina una clase personalizada (los nombres no importan, como Object ...). También en este caso obtendrá la misma SecurityException.

package java.test; public class Test { public static void main(String[] args) { System.out.println("This is Test"); } }


Tu problema con java.lang.Boolean como tu clase booleana, y no con el objeto es simple de explicar.

La clase Object es la raíz de todas las otras clases que puede encontrar, usar o incluso crear. Lo que significa que si pudieras tener la capacidad de anularlo, no funcionaría una sola clase, método o lo que quieras usar, ya que cada uno de ellos depende de esa clase raíz.
Para la clase booleana, no es un tipo booleano, sino una clase para un tipo booleano. Y como nada depende de eso, es posible anularlo.
Una mejor forma de entender este problema es mirar este enlace:
[ http://docs.oracle.com/javase/7/docs/api/overview-tree.html]
Notarás que cada tipo de paquete, que contiene todo tipo de clases de Java, depende de la clase de objeto.

Entonces, la excepción de seguridad que encontró es como un "salvador de vidas" para su programa.
Si me equivoco con su pregunta, otras personas pueden encontrar una respuesta más adecuada. :)


Esto no es un error.

Comportamiento debido a:

Cuando la Máquina Virtual Java (JVM) intenta cargar nuestra clase, reconoce que su nombre de paquete no es válido y, por lo tanto, se lanza una SecurityException. SecurityException indica que se ha producido una violación de seguridad y, por lo tanto, la aplicación no se puede ejecutar. la clase pública SecurityException extiende RuntimeException Lanzada por el administrador de seguridad para indicar una violación de seguridad.

utilice un nombre de paquete diferente, no solo para el paquete de idioma de java.it cubre todo el paquete, no otorga permisos para sobrescribir en clases de compilación y paquetes de Java.

Al cambiar esto, podemos crear o anular el mismo paquete y clase:

a / j2ee.core.utilities / src / org / netbeans / modules / j2ee / core / api / support / java / JavaIdentifiers.java b / j2ee.core.utilities / src / org / netbeans / modules / j2ee / core / api /support/java/JavaIdentifiers.java

**if (packageName.startsWith(".") || packageName.endsWith(".")) {// NOI18N return false; } if(packageName.equals("java") || packageName.startsWith("java.")) {//NOI18N return false; }** String[] tokens = packageName.split("//."); //NOI18N if (tokens.length == 0) { return Utilities.isJavaIdentifier(packageName); a/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java b/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java assertFalse(JavaIdentifiers.isValidPackageName(" ")); assertFalse(JavaIdentifiers.isValidPackageName("public")); assertFalse(JavaIdentifiers.isValidPackageName("int")); assertFalse(JavaIdentifiers.isValidPackageName("java")); assertFalse(JavaIdentifiers.isValidPackageName("java.something"));

}