Java-类加载器笔记

来源:互联网 发布:js 读取数组最后一个 编辑:程序博客网 时间:2024/06/06 16:42
1、类加载器

 Bootstrap Loader:程序运行,在JRE目录寻找jvm.dll,然后启动JVM进行初始化动作,产生BootstrapLoader,BootstrapLoader会加载Extended Loader,并设定Extended Loader的parent为BootstrapLoader,通常用C编写而成,会搜索系统参数sun.boot.class.path中指定位置的类,默认为JRE所在目录的classes下的.class文件或lib目录下.jar文件中的类。


Extended Loader(ExtClassLoader):Extended Loader会加载System Loader,并设定System Loader的parent为Extended Loader,由Java编写而成,会搜索系统参数java.ext.dirs中指定的类,默认为JRE目录下的lib\ext\classes目录下的.classes文件或lib\ext目录下的.jar文件中的类。


System Loader(AppClassLoader):是自定义加载类的parent,由Java编写而成,会搜索系统参数java.class.path中指定位置的类,也就是Classpath所指定的路径,默认为当前工作路径下的.class文件。
可以使用函数 System.getProperty("");语句来显示参数中指定的路径。例如:System.getProperty("sun.boot.class.path");


类加载器的工作规则:
每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。
类加载器是以java.lang.ClassLoader类型存在,每一个类被加载后都会有一个Class的实例来代表,每个Class的实例都会记住自己是由那个加载器加载的。
//获得某个自定义类的Class对象Class c=someclass.getClass();//获得加载器ClassLoaderClassLoader loader=c.getClassLoader();//获得parentClassLoader parent=loader.getParent();


加载类方法:

1、Class.forName("类名称");2、loader.loadClass("类名称");


使用Class.forName("someclass");默认会在加载类的时候,如果类中有定义静态区块则会运行,若不想运行,则使用loadClass(),或者使用如下版本的forNme();

static Class forName(String name,boolean initialize,ClassLoader loader);
其中,默认initialize=true,将initialize设为false则不会在加载类的时候运行静态区块,而在建立类对象时才会运行静态区块,loader是一个加载器,可以指定,也可以使用主线程的加载器:

Thread.currentThread().getContextClassLoader();


取得ClassLoader的实例后,可以使用loadClass()方法来加载类,使用此方法不会运行静态区块,在建立类的实例时才回运行静态区块
自定义一个类加载器,可以使用URLClassLoader来产生新的类加载器,即指定新的搜索路径,需要java.net.URL来作参数。例如:
URL url=new URL("file:/d:/workspace/");ClassLoader urlloader=new URLClassLoader(new URL[]{url});Class c=urlloader.loadClass("someclass");


静态区块

public class Testclass{static{System.out.println("这里是静态区块");}}


使用不同的类加载器加载的类文件会有两份不同的Class实例,如果有两个不同的ClassLoader搜索同一个类,而在parent的AppClassLoader搜索路径中找到了,则Class实例只有一个。


Class c=Class.forName(args[0]);Class[] params=new Class[2];params[0]=String.Class;params[1]=Integer.TYPE;Constructor con=c.getConstructor(params);Object[] obj=new Object[]{"java",new Integer(10)};Object obj=con.newInstance(obj);


//利用反射机制动态生成数组Class c=String.class;Object obj=Array.newInstance(c,5);for(int i=0;i<5;i++)Array.set(obj,i,i+"*");//set(数组,索引,值)for(int i=0;i<5;i++)System.out.print(Array.get(obj,i)+" ");//输出:1* 2* 3* 4* 5*String[] str=(String[])obj;for(String s:str)System.out.print(s+" ");


//建立多维数组Class c=String.class;int[] dim=new int[]{3,4};Object obj=Array.newInstance(c,dim);//建立了一个3*4的数组System.out.println(dim.getClass().getCompontype());//输出:int


原创粉丝点击