首先,这些类型的限制是为了强制实施Java沙箱。也就是说,在受信任的环境中运行不受信任的代码。例如,在浏览器中的计算机(受信任的环境)上从某个站点(您不一定信任该站点)运行小程序。其目的是禁止不受信任的代码访问包私有的东西,这可以帮助它逃离沙盒。
通常,这些限制由 SecurityManager 强制执行,因此当您在命令行上运行自己的应用程序时,它们不应该发生(除非您显式指定使用 SecurityManager)。当你控制环境时,你可以去编辑Java的rt.jar.class字符串定义(从技术上讲,你可以不确定许可说什么)。正如我所说,这些限制通常在SecurityManager中,但是关于java.*包的特定规则在ClassLoader类中。
回答你的问题:我的猜测是java.*检查是因为a)历史原因b)在Java核心的某个地方有一个检查类的名称,比如:所有以java.*开头的类都会得到特殊对待。
但是,请考虑即使您设法创建了一个名为java.lang.String的类,它也与Java核心定义的java.lang.String不是同一类。它只是一个具有完全相同名称的类。类标识不仅仅是类的名称,尽管除非您真正使用ClassLoaders,否则这可能很难感知。
因此,由应用程序类加载器在包 java.lang 中加载的类将无法访问核心 java.lang 包私有内容。
为了说明这一点,请尝试使用main方法创建一个名为javax.swing.JButton的类并执行它。您将获得一个 .这是因为java在你的类之前找到了“真正的”JButton,而真正的JButton没有main方法。java.lang.NoSuchMethodError: main
在 Java 独立应用程序中,您可以通过使用反射和 setAccessible 直接调用私有本机 defineClassx 方法之一来绕过此限制。
顺便说一句:核心java.lang.String保证在你的代码执行之前被加载,因为它在任何地方都被引用,你不会首先用你的用户代码到达那里。JVM 在尝试加载类之前就已经设置到一定程度,更不用说执行它了。