反射
什么是反射
反射java语言中的一种机制,通过机制可以动态的实例化对象,读写属性、调用方法
反射的优点
反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创和控制任何类的对象,无需提前硬编码目标类
反射的缺点
性能问题,使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用
注意:
一定要提供无参构造器
- 默认找的是默认无参构造器。
getConstructor与getDeclaredConstructoe的区别
- getConstructor只能获取被public修饰的构造器
- getDeclaredConstructoe被所有关键字修饰的构造器
当我们想获得某个不能正常情况下获得的类及其内部的属性及方法时,此时就要用到反射,那么如何反射呢,如下:
例如:生成对象: People p = new People();
1、 获取当前类的类型信息(Class对象)
- 1) Class class = People.class;
- 2) Class class = Class.forName(“com.tulun.src9.People”);
- 3) People p = new People();
Class class = p.getClass();
2、 更改属性值:
Field field = c.getDeclaredField(“name”);
field.setAccessible(true); -> 想要访问非公有的成员:-> .setAccessible(true);
field.set(o,“lisi”);
System.out.println(field.get(o));
3、调用p.eat();
1) 先获取构造函数
- Constructor con = c.getDeclaredConstructor();
- new对象
Object o = con.newInstance();
2) 进行函数调用:
- 1、 获取函数
- Method m = c.getMethod();
- 2、 通过对象进行函数调用
- method.invoke(o);
Eg:
class People{
private String name;
private People(String name){
this.name = name;
}
private void eat(){
System.out.println("吃饭");
}
}
//反射 -》private 破坏类的封装性
public class TestDemo{
public static void main(String[] args) throws Exception {
Class c = People.class;
//Object o = new People("zs");
/**
* getConstructor ->在People类中找public修饰的构造
* getDeclaredConstructor -> People类查找构造(所有访问修饰符)
*/
Constructor constructor = c.getDeclaredConstructor(String.class);
//想要访问非公有的成员
constructor.setAccessible(true);
Object o = constructor.newInstance("zs");
//将name值改为lisi p.name = "lisi";
Field field = c.getDeclaredField("name");
field.setAccessible(true);
field.set(o,"lisi");
System.out.println(field.get(o));
//获取一个eat方法,进行函数调用 p.eat()
Method method = c.getDeclaredMethod("eat");
method.setAccessible(true);
method.invoke(o);
}
}
结果:
eg:
toJson
public class People {
private String name;
private int age;
private int id;
private Address address;
private Integer[] arr = {10,20};
public People(String name,int age,int id){
this.name = name;
this.age = age;
this.id = id;
}
public People(String name,String city,String street,int homeId,int age){
this.name = name;
address = new Address(city,street,homeId);
this.age = age;
}
public People(String name,int age){
this.name = name;
this.age = age;
}
private int getValue(int i){
return arr[i];
}
}
public class Address {
private String city;
private String street;
private int homeId;
public Address(String city,String street,int homeId){
this.city = city;
this.street = street;
this.homeId = homeId;
}
}
public class Test {
public static String toJson(Object o, Class c)throws Exception{
String string = "";
Field[] field = c.getDeclaredFields();
for(int i=0;i<field.length;i++){
field[i].setAccessible(true);
String str = "\"" + field[i].getName() + "\"" + ":";
if (field[i].get(o) instanceof String) {
str = str + "\"" + field[i].get(o) + "\"";
} else if(field[i].get(o) instanceof Number){
str = str + field[i].get(o);
}else if(field[i].get(o) instanceof Address){
str = toJson(field[i].get(o),Address.class);
}
else if(field[i].get(o) instanceof Integer[]){
Method method = c.getDeclaredMethod("getValue",int.class);
method.setAccessible(true);
str = "[";
for(int j=0;j<((Integer[]) field[i].get(o)).length;j++){
str = str + method.invoke(o,j);
if (j != ((Integer[]) field[i].get(o)).length-1){
str = str + ",";
}
}
str = str + "]";
}
if(i != field.length-1){
str = str + ",";
}
string += str;
}
return "{" + string + "}";
}
public static void main(String[] args){
// People p = new People("zs",10,1);
People p1 = new People("zs","123","456",666,10);
// People p2 = new People("zs",10);
String str = null;
try {
str = toJson(p1,People.class);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
}
}
结果: