class TestClassA{
public void method(){
System.out.println("Loading ClassA");
}
}
public class ClassLoaderTest {
public static void main(String args[]){
TestClassA testClassA = new TestClassA();
testClassA.method();
}
}
class TestClass{
public void method(){
System.out.println("TestClass-method");
}
}
public class CLTest {
public static void main(String args[]) {
try{
Class c = Class.forName("TestClass");
TestClass object = (TestClass)c.newInstance();
object.method();
}catch(Exception e){
e.printStackTrace();
}
}
}
try{
URL url = new URL("file:/d:/test/lib/");
URLClassLoader urlCL = new URLClassLoader(new URL[]{url});
Class c = urlCL.loadClass("TestClassA");
TestClassA object = (TestClassA)c.newInstance();
object.method();
}catch(Exception e){
e.printStackTrace();
}
父类
|
父类
|
载入
|
载入
|
BootstrapLoader
|
PARENT
AppClassLoader
|
PARENT
ExtClassLoader
|
了解 Java 的类加载机制对我们熟练灵活运用 Java 语言,提高程序的运行效率有着非常重要的作用,知其然也要知其所以然,这样才能从整体提高程序的质量。
以上是个人为了毕业要发表的一篇论文,没有什么深度,下面再继续讨论一点关于ClassLoader的一定东东 :
public class ClassLoaderTest1{
private ClassLoaderTest2 test = null;
public ClassLoaderTest1(){
test = new ClassLoaderTest2();
}
public void method(){
System.out.println("Loading ClassA");
}
}
class ClassLoaderTest2{
public ClassLoaderTest2(){
}
public void method(){
System.out.println("Loading ClassA");
}
}
测试程序:
URL url = null;
try {
url = new URL("file:/E:/JAVA/MyProject/string/");
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLClassLoader cl = new URLClassLoader(new URL[]{url});
URLClassLoader cl1 = new URLClassLoader(new URL[]{url});
try {
Class tempClass = cl.loadClass("ClassLoaderTest1");
Class tempClass2 = cl.loadClass("ClassLoaderTest2");
Object test = tempClass.newInstance();
System.out.println(tempClass.getClassLoader());
System.out.println(tempClass2.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
当ClassLoaderTest1,ClassLoaderTest2在当前目录和E:/JAVA/MyProject/string/都存在的时候输出为sun.misc.Launcher$AppClassLoader@1050169
sun.misc.Launcher$AppClassLoader@1050169
即都是被AppClassLoader加载的, 即使在 E:/JAVA/MyProject/string/下面也存在.
当ClassLoaderTest1,ClassLoaderTest2只在E:/JAVA/MyProject/string/下存在的时候输出为
java.net.URLClassLoader@480457
java.net.URLClassLoader@1a7bf11
即都是被自定义的加载器加载的,并且也可以Object test = tempClass.newInstance();
下面一的是最关键的,因为ClassLoaderTest1需要用到ClassLoaderTest2,如果ClassLoaderTest2被AppClassLoader加载,而ClassLoaderTest1是被自定义的类加载器加载,就会出现如下错误:
java.lang.IllegalAccessError: tried to access class ClassLoaderTest2 from class ClassLoaderTest1
at ClassLoaderTest1.<init>(ClassLoaderTest1.java:6)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
at java.lang.Class.newInstance0(Class.java:308)
at java.lang.Class.newInstance(Class.java:261)
at ClassLoaderTest.main(ClassLoaderTest.java:43)