Java类加载与对象调用

来源:互联网 发布:vnware虚拟机安装linux 编辑:程序博客网 时间:2024/05/02 20:37

最近遇到一个问题:

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(){@Overridepublic 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) {//出现ClassNotFoundExceptione1.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(){}@Overridepublic String toString(){return "abcd";}}

得出的结果是

in : abcdabcdjava.lang.ClassNotFoundException: com.abcd.ABCDat 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.NullPointerExceptionat TestClassLoader.main(TestClassLoader.java:52)

得出结论:

类加载器只有在类加载时会起到指示安全域的作用,但对象一旦被创建后,可以调用其Object的@Override方法

0 0
原创粉丝点击