目录
java反射机制
在运行状态中,任意一个类,都可以知道它的任意属性和方法,任意一个对象,都可以调用它的任意一个方法和属性。
获取反射机制的三种方法:
- 对象获取:
java
//通过对象获取Class对象
User user = new User();
Class c1 = user.getClass();
2.类名获取:
java
//通过类名获取Class对象
Class c2 = User.class;
- 类路径获取:
java
//通过Class获取Class对象
Class c3 = Class.forName("com.yyds.javaReflect.model.User");
获取构造方法
1.首先获取Class对象:
java
//通过对象获取Class对象
User user = new User();
Class c1 = user.getClass();
2.获取无参构造放方法,创建对象
java
//获取无参构造放方法
Constructor constructor1 = c1.getConstructor();
//创建对象
Object user1 = constructor1.newInstance();
3.获取有参构造放方法,创建对象
getConstructor参数为:参数的Class对象
java
//获取有参构造放方法
Constructor constructor2 = c1.getConstructor(int.class,String.class);
//创建对象
Object user2 = constructor2.newInstance(11,"张三");
- 获取私有无参构造方法
setAccessible(true)会取消java语言访问检查,允许访问私有的成员
java
//获取Class对象
Class c2 = Car.class;
// 获取私有无参构造方法
Constructor constructor3 = c2.getDeclaredConstructor();
//setAccessible为true时:取消java语言访问检查
constructor3.setAccessible(true);
//创建对象
Object user3 = constructor3.newInstance();
获取属性
- 获取公共属性:
java
Class c2 = Car.class;
//获取所有公共的属性
Field[] fields = c2.getFields();
for(Field f:fields){
//输出属性名称
System.out.println(f.getName());
}
//输出公共属性的数目
System.out.println(fields.length);
2.获取私有属性:
getDeclaredField()和getDeclaredFields()获取私有属性
java
//获取指定属性名(包含私有)
Field num = c2.getDeclaredField("num");
num.setAccessible(true);
System.out.println(num.getName());
模拟mybatis反射:
java
//模拟mybatis反射
Map<String,Object> map = new HashMap<>();
map.put("num",12);
map.put("colour","黑色");
map.put("id",1);
Object car = c2.newInstance();
//获取所有属性,包括私有
Field[] fields2 = c2.getDeclaredFields();
System.out.println(fields.length);
for(Field f:fields2){
f.setAccessible(true);
f.set(car,map.get(f.getName()));
}
System.out.println(car);
输出:Car{num=12, colour='黑色', id=1}
获取成员方法
与获取属性方法相似
1.获取公共成员方法:
- getMethod(String name, Class<?>... parameterTypes):返回一个
Method
对象,返回类或接口的指定公共成员方法;- getMethods():返回
Method
数组,返回所有类或接口的指定公共成员方法。
2.获取私有成员方法:
- getDeclaredMethods():返回
Method
数组,类或接口的所有指定成员、方法,包含私有;- getDeclaredMethod()方法:返回指定所有方法,包含私有,有参时,第一个参数为方法名,第二个位方法参数的Class对象。
invoke(对象,参数):调用方法
示例:
java
Class c2 = Car.class;
Method[] methods = c2.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m.getName());
}
Object car = c2.newInstance();
Method m1 = c2.getDeclaredMethod("setNum", int.class);
m1.invoke(car, 12);
System.out.println(car);
使用反射机制将对象转为JSON形式
java
public class ObjectToJson {
public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 获取所有属性
Class c = object.getClass();
//获取所有属性
Field[] fields = c.getDeclaredFields();
String res = "{";
for (Field f:fields){
//取消java语言访问检查,允许访问私有的属性
f.setAccessible(true);
res= res + f.getName() +":"+ c.getDeclaredMethod(getGetMethod(f.getName())).invoke(object)+",";
}
res = res.substring(0,res.length()-1)+"}";
return res;
}
//已知属性名返回get、set形式方法名
public static String getGetMethod(String fname){
return "get"+fname.substring(0,1).toUpperCase()+fname.substring(1);
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Car car = new Car(101,"red",1);
User user = new User(1,"tom",12);
String jcar = objectToJson(car);
String juser = objectToJson(user);
System.out.println(jcar);
System.out.println(juser);
}
}