您的位置:首页 > 编程语言 > Java开发

关于自己写的java.lang.String能不能被加载的问题

2017-09-04 23:54 316 查看
如题,作者之前对于自己写的java.lang.String类能不能被加载,一直感到非常困惑,今天写代码证实了一下。上干货。

自己写类加载器:

public class MyClassLoader extends ClassLoader{
public Class findClass(String name){
byte[] b = null;
try {
b = getByte(name);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return defineClass(null, b, 0, b.length);
}
private byte[] getByte(String name) throws IOException{
FileInputStream in = new FileInputStream(name);
byte[] b = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = 0;
while((len = in.read(b)) != -1){
out.write(b, 0, len);
}
out.close();
b = out.toByteArray();
return b;
}
}


测试类(path1,path2是我存放编译后的class文件的路径):

public class MyClassLoaderTest {
public static void main(String [] args) throws Exception{
MyClassLoader myloader = new MyClassLoader();
String path1 = "F:/Software/java/jdk/lib/String.class";
String path2 = "E:/JavaTest/String.class";
Class c = myloader.findClass(path1);
//Class c = myloader.findClass(path2);
Object obj = c.newInstance();
System.out.println(obj.getClass().getName());
Method m = c.getMethod("say", null);
m.invoke(obj, null);
}
}


自己写一个java.lang.String类,编译后放在上述path1,path2下各一份,如下。

package java.lang;
public class String{
public void say(){
System.out.println("I'm String class");
}
}


执行main方法,报错如下:

Exception in thread “main” java.lang.SecurityException: Prohibited package name: java.lang

若String写成下面这样(注意,只是package有变化):

package java;
public class String{
public void say(){
System.out.println("I'm String class");
}
}


则报错如下:

Exception in thread “main” java.lang.SecurityException: Prohibited package name: java

注意,以上两个String类的不同之处,只是package不同。而从它俩的报错来看,jvm不允许我们自己用”java”开头的package。那么我不写package呢?如下:

public class String{
public void say(){
System.out.println("I'm String class");
}
}


执行结果,输出如下:

String
I'm String class


这时候我自己写的String类,被我自己写的类加载器加载成功,并且通过反射机制,执行了其中的say()方法。

那么来一个总结吧。

自己写的类的package名称不可以”java”开头,否则不会被类加载器加载。对于自己写java.lang.String,肯定也不会被加载成功了,即使是自己写的类加载器。这就是双亲委派模型的缘故。而后来我自己写的String类(无package),成功被加载。其实我认为,这时候的类名叫做”String”,还是叫做”Ergou”,都是无所谓的,只是非常普通的一个名字而已,因为所属的包不同,自己写的String和java类库中的java.lang.String并不冲突。

以上,乃个人愚见,谨与诸君分享,若有不对之处,请不吝赐教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: