标签:反射
一 java中类的加载
1 jvm使用一个类的时候,是通过一个ClassLoader,把类加载到内存中,获得该类的Class对象;
2 ClassLoader加载一个类的时候,会检查上级的ClassLoader是否没有加载过该类,若已加载过,不再加载;
二 程序块
静态程序块,在类加载的时候就会被执行,A加载的时候,会将static程序块部分执行;
若去掉static,变成非静态程序块,在A类加载的时候,非静态程序块不会被执行,只有创建实例的时候才会被执行,创建一个实例执行一次;
package com.ob.temp; public class User { public static void main(String[] args) throws ClassNotFoundException { Class.forName("com.ob.temp.A"); } } class A{ static{ System.out.println("A已加载"); } String name; int age; A(){ } A(String name,int age){ this.name=name; this.age=age; } void say(String name,int age){ System.out.println(name+":+age"); } void m1(){ System.out.println("in m1"); } }
二 反射(java.lang.reflect)
1 反射:反射是获取运行的java类的全部信息,包括构造方法,成员变量和方法等;获取的方式是通过,该类对应的Class类对象的方法获取的;
2 创建Class类对象三种方式:
Class.forName("要加载类的完整类路径");
类名.class;
对象的引用.getClass();
Class c1=Class.forName("com.ob.temp.A"); Class c2=A.class; A a=new A(); A a1=new A(); Class c3=a.getClass(); System.out.println(c1==c2); System.out.println(c1==c3);
会返回两个true;
3 通过一个类的Class对象创建实例
Class c1=Class.forName("com.ob.temp.A"); A a=(A) c1.newInstance(); a.m1();
这里是通过Class对象的newInstance()方法返回的;
4 访问构造方法:
Class c1=Class.forName("com.ob.temp.A"); Constructor[] cs=c1.getDeclaredConstructors(); for(Constructor c:cs){ System.out.println(c.getName()); } Constructor c=c1.getDeclaredConstructor(String.class,int.class); A a=(A) c.newInstance("zhangsan",5); System.out.println(a.name+":"+a.age); }
可以访问所有的构造方法,也可以访问指定参数的构造方法,构造方法对象 调用newInstance方法返回实例,可以含有参数;
5 访问成员变量:
Class c1=Class.forName("com.ob.temp.A"); Field[] fs=c1.getDeclaredFields(); for(Field f:fs){ System.out.println(f.getName()); } Field fname=c1.getDeclaredField("name"); System.out.println(fname.getName());
类似于构造方法的访问,可以返回变量数组,也可以返回指定的变量;
Class c1=Class.forName("com.ob.temp.A"); A a=(A) c1.newInstance(); Field[] fs=c1.getDeclaredFields(); for(Field f:fs){ System.out.println(f.getName()+"的初始值是:"+f.get(a)); if(f.getType().equals(String.class)){ f.set(a, "zhangsan"); } if(f.getType().equals(int.class)){ f.setInt(a, 20); } System.out.println(f.getName()+"修改后的值是:"+f.get(a)); }
成员变量的Class对象getType()返回类型对应的Class对象,成员变量的Class对象get(Object obj)返回obj的对象对应的变量值,修改成员变量的值,用setXXX(Object obj,值)XXX根据变量类型决定;
6 访问方法:
Class c1=Class.forName("com.ob.temp.A"); A a=(A) c1.newInstance(); Method[] methods=c1.getDeclaredMethods(); for(Method m:methods){ System.out.println(m.getName()); } Method me=c1.getDeclaredMethod("say", String.class,int.class); System.out.println(me.getName());
既可以得到方法数组,也可以访问指定名称和参数的方法;
Class c1=Class.forName("com.ob.temp.A"); A a=(A) c1.newInstance(); Method me=c1.getDeclaredMethod("say", String.class,int.class); me.invoke(a, "zhang",20);
方法对应的类类对象调用invoke("实例对象",参数列表没有参数可以不写);
标签:反射
原文地址:http://blog.csdn.net/liangwenmail/article/details/47280915