【问题标题】:Why you can not create class in java.lang?为什么不能在 java.lang 中创建类?
【发布时间】:2014-06-18 09:27:52
【问题描述】:

假设我正在通过以下方式创建一个类LangTest.java

package java.lang;

public class LangTest 
{
    public static void show()
    {
        System.out.println("In langTest.show()");
    }
}

在另一个类中,我什至将方法称为:

LangTest.show();

它们都没有给出任何编译问题,但在运行时它会抛出异常。 --

Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang
    at java.lang.ClassLoader.preDefineClass(ClassLoader.java:479)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:614)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    at com.javatpoint.Test.main(Test.java:28)

每当您创建以“java.”开头的包名称时都会发生这种情况。

我的问题是为什么我们不允许在 java.lang 或类似的文件中创建一个类?而且,为什么这种情况下没有编译错误?

【问题讨论】:

    标签: java compilation securityexception


    【解决方案1】:

    我的问题是为什么我们不允许在 java.lang 或类似文件中创建类?

    可以在那里创建一个类。但是出于安全原因,“普通”类加载器不会让您加载它,它只接受来自 JDK 自己的核心 jar 文件的它们。这是为了保护 Java 用户免于运行可能完全破坏其系统的恶意代码(例如破坏沙盒限制)。

    如果您想实现自己的 java.* 类版本,则必须实现自己的 JDK(或至少创建自己的 runtime.jar 版本)。

    另外,为什么在这种情况下没有给出编译错误?

    嗯,JDK标准库也需要同一个Java编译器编译...

    【讨论】:

    • 为什么“JDK标准库也需要编译”?我的意思是 JRE 已经承载了类文件。
    • @user1027056:好吧,Oracle 的某个人已经为您编译了它们。从使用常规 Java 编译器的常规 Java 源文件(大部分情况下)。
    • 我的意思是,它在运行时检查安全问题的方式为什么在编译期间不执行相同的操作?是否存在不会引发此 SecurityException 的非常具体的情况?
    • 然后Oracle 的人无法编译这些类以放入JDK。同样,该类编译,因为它是一个有效的类。 JVM 只是确保你不能从除了 JDK 核心本身之外的任何地方加载这样的类。
    • 想一想,这个信息可能在上下文中。要更改引导类路径 java -X,这正是您需要的选项。 -Xbootclasspath/p:从这里获得参考:[link]stackoverflow.com/questions/4838301/…
    【解决方案2】:

    这个 SecurityException 的原因是,该包中的一个类可能能够公开具有包访问权限的属性,这些属性应该限制为“Java 编程语言设计的基础类”(根据 http://docs.oracle.com/javase/6/docs/api/java/lang/package-summary.html )

    【讨论】:

      【解决方案3】:

      前缀“java”分别为核心 Java 包和 Java 扩展保留。

      这就是为什么你不能声明你的包名以java开头的原因

      它由语言保留,因为它是核心 Java 内容所在的位置。事实上,java.lang 包中的所有内容都默认隐式导入到任何 Java 代码中。

      它包含“Java 编程语言设计的基础类”。 (来自文档)。由于根据定义,用户定义的类不能对语言的设计至关重要,因此禁止您将内容放在那里。允许用户将代码放入 java.lang 包中也是一个问题,因为这会将其中定义的任何包域内容暴露给用户。

      只需更改您的软件包名称(几乎可以更改为其他任何名称),您就可以开始使用了。按照惯例,包名称通常是小写的,但您可以将其命名为对您的项目有意义的任何名称。有关更多信息,请参阅软件包教程。

      要了解更多关于如何声明包的信息,请访问以下链接

      http://www3.ntu.edu.sg/home/ehchua/programming/java/J9c_PackageClasspath.html

      【讨论】:

      • 令人惊讶的是,我刚刚尝试使用包名 javax.zzzz;代码运行成功!!!
      • 是的,我还检查了它是否正常工作..我的错误更新我的答案
      【解决方案4】:

      包 java.util 是 sealed 用于修改。将类添加到此包的一种可能方法是编辑源代码编译您自己的 java 版本(例如 OpenJDK)

      【讨论】:

        【解决方案5】:

        出于安全原因,java.lang 是为 java 类保留的。由于您的代码在语法上是正确的,因此没有编译错误的原因。

        【讨论】:

          猜你喜欢
          • 2015-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 2012-11-04
          • 2011-07-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多