同写一个java.lang.String

81 阅读1分钟
package java.lang;

public class String {

    public static void main(String[] args) {
        System.out.println("hello,java!");
    }
}


包名为java.lang,和jdk中的一样,进行运行之后报错:

    错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
       public static void main(String[] args)
    否则 JavaFX 应用程序类必须扩展javafx.application.Application

这是因为java的双亲委派机制导致的,类加载从高到底进行加载,虽然一开始托付给某个类加 
载器,但是它会向上传递给父类加载器,从父类加载器进行查找这个类,所以查找到了jdk中的   
String,官方自己写的String自然是没有这个main方法的。

package java.lang;

public class Demo {

    public static void main(String[] args) {
        System.out.println("demo");
    }
}


同样在java.lang下新增Demo类,发现运行就报错:
java.lang.SecurityException: Prohibited package name: java.lang
	at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" 


由于安全机制阻止了这个类加载

类加载图示:

image.png

1.BootStrap ClassLoader: jre/lib下的核心类库

2.Extension ClassLoader: jre/lib/ext下的jar包

3.App ClassLoader: 自己项目中写的类

4.Custom ClassLoader: 自定义类加载器,实现方式:继承java.lang.ClassLoader

双亲委派机制的优点:

1.确保核心类不被修改

2.避免重复的类加载