自定义String类创建

时间:2013-01-15 06:59:47

标签: java string class final

我试图在我的eclipse工作区中的java.lang包中创建一个自定义类String。 最初我怀疑同一个包中的同一个类是无法创建的,但令我完全惊讶的是我能够在同一个包中创建一个类(String),即java.lang

现在我很困惑 1)为什么有可能和
2)如果允许,可能是什么原因 3)如果在Java中允许这种类型的java类创建将会有什么用。

3 个答案:

答案 0 :(得分:9)

您可以在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(默认值为1)使用" parent first"策略,所以java.lang类将使用bootstrap类加载器从rt.jar加载。因此,您需要将rt.jar中的String.class替换为您的版本。或者使用-Xbootclasspath/p: java选项覆盖它,该选项预先设置引导类加载器搜索路径的路径。所以你可以

1)将copypaste真正的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

答案 1 :(得分:4)

这称为类阴影。

1。)这是可能的,因为java类不是静态链接的,而是在类加载时链接。

2。)如果不允许,则整个班级加载将更难实现。然后,例如,您还必须针对特定Java版本构建项目。因为Java类可能会从版本更改为版本。这不是一种可维护的方法。

3。)osgi利用它来加载同一个bundle的不同版本。另一个常见的用例是替换框架中的错误类,其中没有其他可行的解决方法。但是应该谨慎使用这种技术,因为错误可能很难调试。

请注意,不允许在java。*包中使用阴影类,因为这会破坏Java安全沙箱。所以你在运行时会遇到问题。

答案 2 :(得分:2)

是的,您可以创建名为 java.lang 的包,也可以创建名为 String 的类。

但是你无法运行你的String类。

1)为什么可能:编译器将成功编译您的类。

2)如果允许,可能是什么原因:您的包和类有一个有效的名称,因此编译器不会抱怨。

3)如果在Java中允许这种类型的java类创建将会有什么用?但是这个String类没有多少用处。 Bootstrap类加载器将从sun的java.lang包中加载类。因此,您的自定义String类不会被加载,因此在运行期间会失败。

Bootstrap类加载器是JVM实现的一部分,它加载Java API类(包括java.lang.String)。对于每个加载的类,JVM都会跟踪哪个类加载器是引导程序还是用户定义的 - 加载了类。因此,任何加载自定义String类的尝试都将失败,因为已经加载了String类。