Java反射机制
反射机制的概念:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
一:获取类的Class对象(类对象),这里创建一个Books实体类用来测试。
类中的属性可以随意定义
public class Books {
private int id;
private String name;
private String type;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
- 第一种方式获取
Books books = new Books();
Class name = books.getClass();
System.out.println(name);
- 第二种方式
Class name = Books.class;
System.out.println(name);
- 第三种(也是用的最多的一种)
try {
//路径为全路径.名称
Class name = Class.forName("com.zsy.Books");
System.out.println(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
- 当然获取到了类对象,就可以实例化调用对象的方法了
try {
Class name = Class.forName("com.zsy.Books");
//调用的是空参数的构造方法
Books books = (Books) name.newInstance();
System.out.println("实例化后的类对象:" + books);
} catch (Exception e) {
e.printStackTrace();
}
运行效果:
二:使用java.lang.reflect.Field类,获取类中私有、以及公有等全部属性和属性的信息。
1.创建一个Books对象设置一些信息
Books books = new Books();
books.setId(1);
books.setName("疯狂Android");
books.setType("程序员");
2.通过books对象得到类对象,在使用类对象获得books对象的属性,以及属性类型
Class name = books.getClass();
Field[] fields = name.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName() + "属性的类型:" + field.getType());
}
运行效果:
这里需要注意的是getFields() 只可以获取到共有属性 (public)而getDeclaredFields() 可以将私有属性获取到(private)
3.通过books对象得到类对象获取属性的值,当获取的是private(私有属性时) 需要设置访问权限field.setAccessible(true);
Class name = books.getClass();
Field[] fields = name.getDeclaredFields();
for (Field field : fields) {
//当获取private属性是,需要设置访问权限
field.setAccessible(true);
try {
System.out.println(field.getName() + "属性的值:" + field.get(books));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
三:使用java.lang.reflect.Method类,获取类中私有,以及公有等全部方法(继续使用上面创建的books对象)。
1.获取对象的所有方法名称、返回值类型、以及参数信息
/**
* 获取对象的所有方法名称
*/
public static void getMethod(Books books) {
Class cls = books.getClass();
//获取对象中的所有方法
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
System.out.print("方法名称:" + method.getName() + "\t");
System.out.print("方法修饰符:" + method.getModifiers());
//获取真正的修饰符
System.out.print("(" + Modifier.toString(method.getModifiers()) + ")\t");
System.out.print("方法返回值类型:" + method.getReturnType() + "\t");
//得到方法的参数类型
Class[] parameters = method.getParameterTypes();
}
}
运行效果:
2.接下来就是好玩的东西了,通过反射来调用对象中的所有方法这个;这个也是在实际运用中也是用到最多的。
Class cls = books.getClass();
//调用无参数的方法
Method method = cls.getMethod("getName", null);
Object invoke = method.invoke(books, null);
System.out.println(invoke);
运行效果:
cls.getMethod(String name, Class< ? >… parameterTypes);第一个参数为调用的方法名,第二个为参数为 类型.class 数组。
method.invoke(Object obj, Object… args);第一个参数为调用的方法的对象,第二个为参数为参数的值。
下面调用一个多个参数的函数,来理解这两个函数的参数。
2.在Books中添加一个函数,用来测试。
public String doubleParm(String s, int i) {
return s + "-" + i;
}
//new Class[]{}参数类型
Method doubleParm = cls.getMethod("doubleParm", new Class[]{String.class, int.class});
//new Object[]{}与参数类型对应的值
Object invoke = doubleParm.invoke(books, new Object[]{"Hello", 10});
System.out.println(invoke);
运行效果: