class 类:类的实例表示正在运行的 java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 class 对象。一个class对象表示表示的是一种类型,但这个类型未必是一种类,比如int.class是一个class对象,而int不是类。
field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 field 类不同,field 类封装了反射类的属性,而 constructor 类则封装了反射类的构造方法。
method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法。这个类不难理解,它是用来封装反射类方法的一个类。
如何获得字节码?
class cls = xxx.class;
class cls = xx.getclass();
class.forname(类名);// 返回字节码:若内存中有加载该类,则他找到该类的字节码并返回,若无,则找到该类的路径,加载后返回。
要区别一个概念,这里获得的是类的字节码,与具体的对象无关。
如何获得实例?
test t1=new test();
object t2 =t1.getclass().newinstance();
object t3 =class.forname("test").newinstance();
newinstance方法调用没有参数的构造器,如果带参数就需要使用constructor类。
class类中的getfields、getmethods、getconstructors将返回类支持的public域、方法、和构造器数组,包括超类的公有成员。
class类中的getdeclarefields、getdeclaremethods、getdeclareconstructors将返回类中声明的全部域、方法、和构造器数组,其中包括私有的和保护的,但不包括超类的成员。
field、method、constructor都有一个getmodifiers方法,可以使用其枚举值判断修饰符,或者modifier.tostring方法等解析。
accessibleobjecte是field、method、constructor公共超类,调用setaccessible(true)方法后可以对实例的保护和私有成员设置新值。这个特性是为调试、持久存储相似机制提供的。
使用method类型作为函数参数可以实现c#中的委托,使用接口回调执行快些。
import java.lang.reflect.accessibleobject;
import java.lang.reflect.array;
import java.lang.reflect.constructor;
import java.lang.reflect.field;
import java.lang.reflect.method;
import java.lang.reflect.modifier;
import javax.accessibility.accessiblerole;
public class reflecttest {
public static int a = 47;
private string str = "hello";
public reflecttest() {
}
public reflecttest(string str) {
this.str = str;
}
public string getstr(string str) {
return this.str + "," + str;
}
public string getstr() {
return str;
}
public static void methodtest(object object) {
};
public static void main(string[] args) throws exception {
reflecttest instance = new reflecttest();
// 获取字节码
class clazz = class.forname("reflecttest");
// 获取字段信息
field fielda = clazz.getfield("a");
fielda.getname();
fielda.gettype();
modifier.tostring(fielda.getmodifiers());
fielda.getint(instance);
fielda.get(instance);
//设置私有成员
field fieldstr = clazz.getdeclaredfield("str");
fieldstr.setaccessible(true);
// accessibleobject.setaccessible(array, flag)
fieldstr.set(instance, "abc");
// 根据字节码构造实例
constructor constructor = clazz.getconstructor();
instance = constructor.newinstance();// 无参
instance = (reflecttest) clazz.newinstance(); // 无参
constructor = clazz.getconstructor(string.class);// 有参
instance = constructor.newinstance("world");
// 调用指针函数
method method1 = instance.getclass().getmethod("getstr");
method1.invoke(instance);//无参
method1 = instance.getclass().getmethod("getstr", string.class);
method1.invoke(instance, "string str");// 有参
method1 = instance.getclass().getmethod("methodtest", object.class);
method1.invoke(null, "object");// 静态
}
// 使用反射编写通用的数组代码
static object goodarrygrow(object src) {
class cl = src.getclass();
if (!cl.isarray())
return null;
class componenttype = cl.getcomponenttype();
int length = array.getlength(src);
int newlength = length * 11 / 10 + 10;
object dest = array.newinstance(componenttype, newlength);
system.arraycopy(src, 0, dest, 0, newlength);
return dest;
}
}
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/