欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA classLoader

程序员文章站 2022-06-20 16:19:46
...
JDK内置ClassLoader
1.bootstrap class loader 
最顶层的 负责管理一些classloader 
implemented by native lauguage c 汇编 C++ 操作系统本地语言 无名字(null)
load the core classes of jdk
首先是bootstrap class loader  把其他的classloader load 进来,然后其他的classloader负责把class load进来。

System.out.println(String.class.getClassLoader());
output:null


2.JDK\jre\lib\ext\*jar
extension classLoader 负责加载 其他均匀JAVA语言实现
System.out.println(
com.sun.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName());


3.Application class loader 加载自己定义的类
System.out.println(JdkClassLoader.class.getClassLoader().getClass().getName());
System.out.println(ClassLoader.getSystemClassLoader());


4.其他的classloader可以通过classloader的继承了解
URLClassLoader 也可以自定义自己的classloader


ClassLoader的层次关系  不是继承关系
public final ClassLoader getParent()
这里说的是对象之间的关系  而不是类之间的关系

Application class loader 有个引用指向extension classLoader
extension classLoader  有个引用(Parent)指向bootstrap class loader

public class JdkClassLoader {

	public static void main(String[] args) {

		ClassLoader c = JdkClassLoader.class.getClassLoader();
		while(c!=null){
			System.out.println(c.getClass().getName());
			c = c.getParent();
		}
	}

}


String.class
如果一个classLoader 的getParent()已经加载,那这个classloader不用加载了


站在classloader的角度,每一个loader进来的class文件是一个class对象,class里面的方法,参数,属性也可以堪称一个对象 property method argm1

java.lang.reflect
Field Methods class



import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestReflection {

	//读取test.properties文件 并生成指定对象
	public static void main(String[] args) {

		/*String str = "T";
		T t = new T();*/
		//动态加载
		String str = "T";
		try {
			Class c = Class.forName(str);
			//生成一个对象
			Object o = c.newInstance();
			
			Method[] methods = c.getMethods();
			
			for(Method m : methods){
				//System.out.println(m.getModifiers()+"\t"+m.getName());
			}
			
			//如何去调用方法
			for(Method m : methods){
				if(m.getName().equals("mm")){
					//m.invoke(c, null);
					//m.invoke(c, new Object[]{});
					//m.invoke(T.class, new Object[]{});
					//动用需要的是类的对象而不是class对象 invoke是可变参数方法
					m.invoke(o);
				}
				
				if(m.getName().equals("m1")){
					m.invoke(o, 1,2);
					//可以了解方法的信息 类似于反汇编
					//不知道方法怎么具体实现
					m.getParameterTypes();
					for(Class pt : m.getParameterTypes()){
						System.out.println(pt.getName());
					}
				}
				
				if(m.getName().equals("getS")){
					Class rt = m.getReturnType();
					System.out.println(rt.getName());
				}
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

}

	/**
	 * 反射机制:可以在运行期间动态的加载一个类进来,动态的new一个对象
	 * 动态的去了解类的内部结构,动态的去调用对象的抹一些方法
	 * 
	 * 配置文件中只需写类的名字,然后就可以动态加载进来
	 * 在Spring Struct中 很多类要配置在配置文件中得
	 * */

class T{
	
	//验证T是否被加载进来
	static {
		System.out.println("T loaded!");
	}
	
	public T(){
		System.out.println("T constructed!");
	}
	
	int i;
	String s;
	
	public void m1(int i,int j){
		this.i = i+j;
		System.out.println(this.i);
	}
	
	public String getS(){
		return s;
	}
	
	public void mm(){
		System.out.println("mm invoked!");
	}
}