------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
JAVA反射,在程序运行状态中,对于任意一个对象都可以拿到它的相关的属性以及方法,并且可以调用它的方法。
看看下面示例,了解相关的方法:
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionTest {
public static void main(String[] args) throws Exception {
String str = "dada";
//获取字节码对应的实例对象
Class cls1 = str.getClass();
Class cls2 = Class.forName("java.lang.String");
Class cls3 = String.class;
//isPrimitive()判断该对象是否是原始数据类型
System.out.println(cls1.isPrimitive());
//true
System.out.println(void.class.isPrimitive());
//true, Integer.TYPE表示所包装类型里面int的字节码
System.out.println(int.class == Integer.TYPE);
//true, 数组类型的实例对象, 判断对象是不是数组
System.out.println(int[].class.isArray());
System.out.println(String[].class.isArray());
//获取指定类的构造函数, 注意: 根据构造函数的参数获取
Constructor cons = String.class.getConstructor(StringBuffer.class);
//实例化类
String str2 = (String)cons.newInstance(new StringBuffer("adada"));
System.out.println(str2);
//用默认的不带参数的构造方法实例化对象
String str3 = String.class.newInstance();
str3 += "ss";
System.out.println(str3);
Person p = new Person(3, 5);
//获取指定对象的指定成员变量的字段, private的不能获得
Field field = Person.class.getField("y");
//获取指定实例化对象的具体值
int y = (int)field.get(p);
System.out.println(y);
//暴力反射
//获取指定对象的指定成员变量的字段, private的可以获得
Field field2 = Person.class.getDeclaredField("x");
//设置private可以被访问
field2.setAccessible(true);
int x = field2.getInt(p);
System.out.println(x);
changeStringValue(p);
System.out.println(p);
//获取指定类的方法
Method methodCharAt = String.class.getMethod("charAt", int.class);
//执行所获取的方法
System.out.println(methodCharAt.invoke(str, 1));
//获取接受数组参数的成员方法
Method methodMain = Test.class.getMethod("main", String[].class);
methodMain.invoke(null, new Object[]{new String[]{"111","222","333"}});
//methodMain.invoke(null, (Object)new String[]{"111","222","333"});
String[] oStrings = new String[]{"dadada","dadadaedef"};
printObject(oStrings);
}
//打印数组中的元素(打印对象)
private static void printObject(Object object) {
Class clazz = object.getClass();
if (clazz.isArray()) {
//返回该数组对象的长度
int len = Array.getLength(object);
for(int i =0;i<len;i++){
//返回指定对象, 指定的第几个元素
System.out.println(Array.get(object, i));
}
} else {
System.out.println(object);
}
}
//将一个任意对象中的所有String类型的成员变量所对应的字符串内容中的"b"换成"A"
public static void changeStringValue(Object object) throws Exception{
//改变非private修饰的成员变量的值
Field[] fields = object.getClass().getFields();
for (Field field : fields) {
if(field.getType()==String.class){
String oldStr = (String) field.get(object);
String newStr = oldStr.replace('b', 'A');
field.set(object, newStr);
// System.out.println(newStr);
}
}
//改变private修饰的成员变量的值
fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
if(field.getType()==String.class){
field.setAccessible(true);
String oldStr = (String) field.get(object);
String newStr = oldStr.replace('b', 'A');
field.set(object, newStr);
}
}
}
}
class Test{
public static void main(String[] args) {
for (String string : args) {
System.out.println(string);
}
}
}
再看看下面的示例,反射机制的运用。利用反射机制在ArrayList<Integer>中插入一个String类型的数据:
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ReflectionTest2 {
public static void main(String[] args) throws Exception {
// 在Integer的ArrayList中添加String类型的数据
ArrayList<Integer> arr = new ArrayList<Integer>();
Method[] methodArr = arr.getClass().getMethods();
methodArr[0].invoke(arr, "adad");
System.out.println(arr);
}
}