关于自己写的java.lang.String能不能被加载的问题
2017-09-04 23:54
316 查看
如题,作者之前对于自己写的java.lang.String类能不能被加载,一直感到非常困惑,今天写代码证实了一下。上干货。
自己写类加载器:
测试类(path1,path2是我存放编译后的class文件的路径):
自己写一个java.lang.String类,编译后放在上述path1,path2下各一份,如下。
执行main方法,报错如下:
Exception in thread “main” java.lang.SecurityException: Prohibited package name: java.lang
若String写成下面这样(注意,只是package有变化):
则报错如下:
Exception in thread “main” java.lang.SecurityException: Prohibited package name: java
注意,以上两个String类的不同之处,只是package不同。而从它俩的报错来看,jvm不允许我们自己用”java”开头的package。那么我不写package呢?如下:
执行结果,输出如下:
这时候我自己写的String类,被我自己写的类加载器加载成功,并且通过反射机制,执行了其中的say()方法。
那么来一个总结吧。
自己写的类的package名称不可以”java”开头,否则不会被类加载器加载。对于自己写java.lang.String,肯定也不会被加载成功了,即使是自己写的类加载器。这就是双亲委派模型的缘故。而后来我自己写的String类(无package),成功被加载。其实我认为,这时候的类名叫做”String”,还是叫做”Ergou”,都是无所谓的,只是非常普通的一个名字而已,因为所属的包不同,自己写的String和java类库中的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并不冲突。
以上,乃个人愚见,谨与诸君分享,若有不对之处,请不吝赐教。
相关文章推荐
- java能不能自己写一个类叫java.lang.System/String正确答案
- java能不能自己写一个类叫java.lang.System/String正确答案
- 能不能自己写个类,也叫java.lang.String
- java能不能自己写一个类叫java.lang.System/String正确答案
- 能不能自己写个类,也叫 java.lang.String?
- java能不能自己写一个类叫java.lang.System/String正确答案
- 【Android开发之坑爹问题】关于"java/lang/String"类型
- java能不能自己写一个类叫java.lang.System/String?
- 2.1 :java能不能自己写一个类叫java.lang.System/String正确答案
- 关于There is no getter for property named 'mohuname' in 'class java.lang.String'] with root cause问题
- java能不能自己写一个类叫java.lang.System/String正确答案
- 能不能自己写个类,也叫 java.lang.String?
- Java学习--能不能自己写个类,也叫System.lang.String?
- 【Java面试题】53 能不能自己写个类,也叫java.lang.String?
- 关于Mybatis "There is no getter for property named 'XXX' in class java.lang.String"的问题
- jsf配置问题 Error performing conversion of value ' of type class java.lang.String to type class
- “JAVA.LANG.NOCLASSDEFFOUNDERROR” 关于CLASSPATH设置问题
- "java.lang.NoClassDefFoundError"错误——一个关于classpath设置的问题
- 关于Tomcat错误java.lang.NoClassDefFoundError: javax/el/ExpressionFactory的问题