Java类加载与对象调用
最近遇到一个问题:
1. 我的类A
2. ThreadB线程的类加载器ClassLoaderB没有加载权限
3. 使用另一个线程ThreadA的类加载器ClassLoaderA加载类A,创建对象a
4. 将a给线程ThreadB,然后调用其toString()方法
5. 发现调用的是类A的toString(),而不是Object的toString()
具体代码如下
import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.util.concurrent.CountDownLatch; public class TestClassLoader { public static Object obj; public static void main(String[] args) { AClassLoader cl = new AClassLoader(); cl.addURL("a.jar"); final CountDownLatch cdl = new CountDownLatch(1); Thread t = new Thread(new Runnable(){ @Override public void run() { try { Class<?> cls = Thread.currentThread().getContextClassLoader().loadClass("com.abcd.ABCD"); try { obj = cls.newInstance(); System.out.println("in : " + obj.toString()); cdl.countDown(); } catch (Exception e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }); t.setContextClassLoader(cl); t.start(); try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(obj); Class<?> cls = null; try { cls = Thread.currentThread().getContextClassLoader().loadClass("com.abcd.ABCD"); } catch (ClassNotFoundException e1) { //出现ClassNotFoundException e1.printStackTrace(); } try { obj = cls.newInstance(); System.out.println("in : " + obj.toString()); } catch (Exception e) { e.printStackTrace(); } } } class AClassLoader extends URLClassLoader{ public AClassLoader(){ super(new URL[0]); } public void addURL(String filePath){ File file = new File(filePath); URI uri = file.toURI(); try { addURL(uri.toURL()); } catch (MalformedURLException e) { e.printStackTrace(); } } }
类ABCD的代码
import java.lang.System; import java.lang.String; public class ABCD{ public ABCD(){ } @Override public String toString(){ return "abcd"; } }
得出的结果是
in : abcd abcd java.lang.ClassNotFoundException: com.abcd.ABCD at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 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:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at TestClassLoader.main(TestClassLoader.java:46) java.lang.NullPointerException at TestClassLoader.main(TestClassLoader.java:52)
得出结论:
类加载器只有在类加载时会起到指示安全域的作用,但对象一旦被创建后,可以调用其Object的@Override方法
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。