1、类加载器
可以使用函数 System.getProperty("");语句来显示参数中指定的路径。例如:System.getProperty("sun.boot.class.path");
类加载器的工作规则:
每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。
类加载器是以java.lang.ClassLoader类型存在,每一个类被加载后都会有一个Class的实例来代表,每个Class的实例都会记住自己是由那个加载器加载的。
取得ClassLoader的实例后,可以使用loadClass()方法来加载类,使用此方法不会运行静态区块,在建立类的实例时才回运行 静态区块。
自定义一个类加载器,可以使用URLClassLoader来产生新的类加载器,即指定新的搜索路径,需要java.net.URL来作参数。例如:
使用不同的类加载器加载的类文件会有两份不同的Class实例,如果有两个不同的ClassLoader搜索同一个类,而在parent的AppClassLoader搜索路径中找到了,则Class实例只有一个。
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.getProperty("");语句来显示参数中指定的路径。例如:System.getProperty("sun.boot.class.path");
类加载器的工作规则:
每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。
类加载器是以java.lang.ClassLoader类型存在,每一个类被加载后都会有一个Class的实例来代表,每个Class的实例都会记住自己是由那个加载器加载的。
//获得某个自定义类的Class对象
Class c=someclass.getClass();
//获得加载器ClassLoader
ClassLoader loader=c.getClassLoader();
//获得parent
ClassLoader 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