------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
反射开始学起来是晦涩难懂的,但是却能让你在无形中提高水平
首先我想说明字节码的概念,即.class文件,他是.java被编译器编译过后的产物,每一个类都拥有属于他自己独特的字节码,String,int[],你自己的Student类等等,反射就是在这一层次上进行操作,由于我也是小试牛刀,只能讲讲初步的用法和理解。
—— Field
在你定义类的时候一般都有对应的成员变量
class student{
private String name;
String ID;
}
student s=new student();
Field field=s.getClass().getField("name");
在这里我们获取了student类中的name成员变量,field在这里是Field的一个实例,他能操作相应对象的成员变量
这个field并不指向一个具体的对象,当你在调用他的方法的时候需要指定具体的对象
field.set(s,"Jack");
这里便是将s的name置为“Jack”;
问题:暴利反射
但是name是private的,field提供了这样的一个方法
field.setAccessible(true);
那么即使是私有变量我们也可操作
问题:getFields()和getDeclaredFields()的区别
前期返回该类以及父类的所有public和默认修饰符的成员变量
后者返回本类的所有的成员变量(包含private)
——Constructor
继续以sudent为例。
Constructor[] constructors=s.getClass().getDeclaredConstructors();
Constructor constructor=s.getClass().getConstructor((参数的字节码)) 获得你想要的构造函数
constructor.newInstance((相应的构造函数的参数))
返回student类的所有构造函数
通过s.getClass().newInstance()也能创建一个实例,但只能调用默认的构造函数,如果没有,则会抛出错误
——Method和Modifier
Method[] methods=s.getClass().getMethods();
for(Method method:methods)
{
String name=m.getName();
if(Modifier.isPublic(method.getModifiers()))
method.invoke(s,"")
Class[] parameters=m.getParameterTypes();
for(class p:parameters)
{
system.out.println(p.getName())
}
}
选出修饰符为public的方法进行操作
取出方法的参数类型进行操作
——Array
这里我起初一直不能理解,但是接触多了,慢慢就有感觉了
判断一个数组的字节码是否相同以他的类型和维度作为标准
static Object goodArray(Object o)
{
Class c=o.getClass();
if(!c.isArray()) return null;
Class componentType=c.getComponentType();
int length=Array.getLength(o);
int newLength=length+10;
Object newArray=Array.newInstance(componentType,newLength);//数组特有方法
system.arraycopy(o,0,newArray,0,length)
return newArray;
}
很经典的一段代码,将旧的数组的内容复制到新的数组中,然后将新数组返回
这里我们并不知道o是什么类型,但是通过反射我们可以得到他的类型和长度
然后创建一个同样类型的新数组
这就是反射的作用,在不知道对象的具体类型的时候,我们可以获取他的信息,从而进行一系列操作