java建立test_创建一个java.lang.Test类,能被加载吗?

java中类加载器有三种:

Bootstrap类加载器 负责加载java的核心类包,比如rt.jar

拓展类加载器 负责加载java的拓展类包

应用类加载器 负责加载我们项目classpath下的类

假如我们自定义了一个java.lang.Test的类,尝试查看哪个类加载器会加载这个类?

public static void main(String[] args) {

Test test = new Test();

ClassLoader classLoader = test.getClass().getClassLoader();

System.out.println(classLoader);

}

Exception in thread "main" 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 TestClazz.main(TestClazz.java:11)

可见这种自定义的用java开头的包名是不能被类加载器加载的。

问题,那为什么java的核心类包里的类可以被加载呢?java.lang.String怎么就不报异常呢?原因很简单,因为java.lang.String类使用到的类加载器是BootStrap类加载器,不会有这个校验,我们自定义的类java.lang.Test即使要去被加载,也由于处于我们classpath下,最后尝试去加载它的是我们的应用类加载器,而应用类加载器加载类的时候会有下面的一个校验方法

private ProtectionDomain preDefineClass(String name,ProtectionDomain pd){

if (!checkName(name))

throw new NoClassDefFoundError("IllegalName: " + name);

// 这里会校验类名不能是java.开头的

if ((name != null) && name.startsWith("java.")) {

throw new SecurityException

("Prohibited package name: " +

name.substring(0, name.lastIndexOf('.')));

}

if (pd == null) {

pd = defaultDomain;

}

if (name != null) checkCerts(name, pd.getCodeSource());

return pd;

}

可见应用类加载器在加载类时候,不能加载java.开头的类,所以尝试加载上述自定义的类会抛出异常。

***************************************分割线************************************

那假如我们定义一个java.lang.String类,会有什么后果呢,这个类是核心类包中已经有的类了。

public static void main(String[] args) {

java.lang.String test = new String();

ClassLoader classLoader = test.getClass().getClassLoader();

System.out.println(classLoader);

}

运行结果时null,表名是bootstrap类加载器,并且加载的是核心类包里的String类,并不是自己定义的这个,可见即使自己定义了核心类包里的同名类,最后的结果是类加载器会加载核心类包里的,自己定义的不会被加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值