---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
1、 反射:Java程序中的各个Java类属于同一个事物,描述这类事物的Java类名就叫class
人——persion
2、Class的实例代表内存的字节码,当我们用到一个类的时候首先要从硬盘上把这个类的二进制码编译成class放在硬盘上,要把字节码加载到内存里面来,再用这个字节码复制出一个一个的对象来
制定一个类完整的名称,也是得到这个类的字节码
Class.forName(“java.lang.String”)得到一个类的字节码,有两种方式,一种是这个类的字节码以前加载过已经在内存里面,还有种是用类加载器加载,加载过后就缓存起来.
得到字节码的方式:
类名点class
New Date().getClass()
Class.forName(String string)
Integer.Type包装类型的字节码,int.class==integer.type
3、 反射就是把Java类中的每一个成分解析成一个相应的Java类
1、Constructor代表某个类中的一个构造方法
得到某个类的所有构造方法:
Constructor[] constructor = class.forName(”java.lang.String”).getConstructors()
得到某一个构造方法:
Constructor constructor = class.forName(”java.lang.String”).getconstructor(StringBuffer.Class)这是要用到的那个构造方法,所以传入StringBuffer.Class
创建实例对象:
通常用法:String str = new String(new StringBuffer(“abc”));
反射方式:String str = (String)constructor.newinstance(newStringBuffer(“abc”));
编译时只知道你是一个constructor构造函数却不知道是哪一个类的,所以用到强制转型,后面传的StringBuff参数,是因为上面得到的是StringBuffer参数的这个构造方法,所以应该传入相应的参数
2、 Field成员变量的反射
//Field反射
ReflectPointpoint = new ReflectPoint(6, 8);
//通过getField()获取成员变量,如果私有了就通过getDeclaredField()获取
java.lang.reflect.Fieldfield = point.getClass().getField("y");
java.lang.reflect.Fieldfield2 = point.getClass().getDeclaredField("x");
field2.setAccessible(true);//暴力反射,x是私有的用getDeclaredField看到了却拿不到所以用暴力反射拿取
System.out.println(field.get(point));//Field.get()明确获取的是哪个对象的元素
3、 Method类里面的方法反射
//Method反射
String str= “adc”;
//第一个参数是表示用什么方法,第二个参数是方法参数
Methodmethod = String.class.getMethod("charAt", int.class);
//第一个参数表示对象,在哪个对象里面调用方法,第二个参数是方法的参数
System.out.println(method.invoke(str,1));
具体代码如下:
新建一个类:
public class ReflectPoint {
private int x;
public int y;
public String a="abcderb";
public String b="bbkdbshbb";
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
return a+"-----"+b;
}
}
反射代码:
public static void main(String[] args) throws Exception{
//Constructor反射
String str = new String(new StringBuffer("adc")); //普通创建对象
//通过字节码拿到某个类的某个构造方法,通过getConstructor()拿到你要的是哪个构造方法
//所以传入需要构造方的字节码,拿到构造方法过后实例化对象通过newInstance(),在传入构造方法需要的参数
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
String Cotstr = (String)constructor.newInstance(new StringBuffer("abc"));
//Field反射
ReflectPoint point = new ReflectPoint(6, 8);
//通过getField()获取成员变量,如果私有了就通过getDeclaredField()获取
java.lang.reflect.Field field = point.getClass().getField("y");
java.lang.reflect.Field field2 = point.getClass().getDeclaredField("x");
field2.setAccessible(true);//暴力反射,x是私有的用getDeclaredField看到到了却拿不到所以用暴力反射拿取
System.out.println(field.get(point));//Field.get()明确获取的是哪个对象的元素
//通过反射改变ReflectPoint对象里面的String元素值,把b改成q
changString(point);
System.out.println(point);
//Method反射
Method method = String.class.getMethod("charAt", int.class);
//第一个参数表示对象,在哪个对象里面调用方法,第二个参数是方法的参数
System.out.println(method.invoke(str, 1));
}
private static void changString(ReflectPoint point) throws Exception{
//获取多有的元素
java.lang.reflect.Field[] field = point.getClass().getFields();
for (java.lang.reflect.Field field2:field) {
//字节码只有一份所以用==相比
if(field2.getType()==String.class){
String oldValue = (String)field2.get(point);
String newValue = oldValue.replace('b', 'q');
field2.set(point, newValue);
}
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------