Ответ 1
Вы можете создать новый класс в пакете java.lang. Если было запрещено, как разработчики Oracle могли бы вообще развивать Java? Я уверен, что они используют тот же javac, что и мы.
Но вы не сможете загрузить его, потому что java.lang.ClassLoader(который распространяется любой загрузчик классов) не позволяет этого, каждый загружаемый класс проходит через эту проверку
...
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException
("Prohibited package name: " + name.substring(0, name.lastIndexOf('.')));
}
...
чтобы вы оказались в чем-то вроде
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:649)
at java.lang.ClassLoader.defineClass(ClassLoader.java:785)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at Test1.main(Test1.java:11)
Что касается классов, которые теневают существующие классы, такие как ваш java.lang.String
, они не могут быть загружены, потому что System ClassLoader (по умолчанию один) использует стратегию "родительский первый", поэтому классы java.lang будут загружаться из rt.jar с помощью загрузчика bootstrap. Поэтому вам нужно будет заменить String.class в rt.jar вашей версией. Или переопределить его с помощью опции -Xbootclasspath/p:
java, которая добавляет пути к пути поиска загрузчика класса загрузки. Таким образом, вы можете
1) copypaste real String.java содержимое в ваш String.java
2) измените метод, например
public static String valueOf(double d) {
return "Hi";
}
и скомпилируйте свой String.java
3) создать тестовый класс
public class Test1 {
public static void main(String[] args) throws Exception {
System.out.println(String.valueOf(1.0d));
}
}
4) запустите его как
java -Xbootclasspath/p:path_to_your_classes Test1
и вы увидите
Hi