The restriction on java.lang
classes is a runtime restriction, not a compile time one.
The JVM actually specifically provides a mechanism for overriding classes in java.lang
. You can do it using the -Xbootclasspath
command line flag:
-Xbootclasspath:bootclasspath
Specifies a semicolon-separated list of directories, JAR files, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java platform JDK.
Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed because doing so would contravene the Java Runtime Environment binary code license.
-Xbootclasspath/a:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to append to the default bootstrap class path.
-Xbootclasspath/p:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to add in front of the default bootstrap class path.
Do not deploy applications that use this option to override a class in rt.jar because this violates the Java Runtime Environment binary code license.
However, as I've already emphasized with bold marks, doing so is a violation of the Oracle Binary Code License Agreement for Java SE and JavaFX Technologies:
D. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "javafx", "sun", “oracle” or similar convention as specified by Oracle in any naming convention designation. You shall not redistribute the Software listed on Schedule 1.
Apart from the above, you may add whatever class you want to whatever packages you want; it's specifically discussed in the the JLS §13.3:
13.3. Evolution of Packages
A new top level class or interface type may be added to a package without breaking compatibility with pre-existing binaries, provided the new type does not reuse a name previously given to an unrelated type.
If a new type reuses a name previously given to an unrelated type, then a conflict may result, since binaries for both types could not be loaded by the same class loader.
Changes in top level class and interface types that are not public and that are not a superclass or superinterface, respectively, of a public type, affect only types within the package in which they are declared. Such types may be deleted or otherwise changed, even if incompatibilities are otherwise described here, provided that the affected binaries of that package are updated together.