为热爱编程的你点赞!
学习SpringBoot实战课程 https://edu.csdn.net/course/detail/31433
学习SpringCloud入门课程 https://edu.csdn.net/course/detail/31451
前言
反射是Java的重要技能,掌握反射后就有利于掌握各种Java框架的底层原理。
什么是反射机制
反射是程序运行时动态获得类的方法、属性、构造方法等内部成员的信息,动态创建类的对象,调用类的属性和方法。
反射可以做什么
极大提高程序的灵活性,从而可以编写出非常通用的代码。
主流的企业级框架都大量使用了反射机制:Spring、Hibernate、MyBatis、Shiro等。
反射的优缺点
优点:灵活性、通用性
缺点:降低代码可读性,程序性能
反射的API
java.lang.reflect包
- Class类 类的类型
- Method类 类的方法
- Field类 类的属性
- Constructor类 类的构造方法
反射
使用反射的过程
- 获得Class对象
- 通过Class对象获得类的方法和属性
- 通过反射机制创建对象
- 通过对象调用方法和属性
获得Class的几种方式
- 类名.class 通过类获得
- 对象.getClass() 通过对象获得
- Class.forName(“包名+类名”) 动态加载类到内存中
运行时获得类的属性和方法信息
Class类的方法:
- Method[] getDeclaredMethods() 获得所有已声明的方法
- Field[] getDeclaredFields() 获得所有已声明的属性
Method的方法:
- String getName() 获得方法名
- Class getReturnType() 获得返回值类型
- int getModifiers() 获得访问修饰符
- Class[] getParameterTypes() 获得所有参数类型
Field的方法:
- String getName() 获得方法名
- Class getType() 获得类型
- int getModifiers() 获得访问修饰符
创建对象,调用方法和属性
Class类的方法:
- Object newInstance() 创建对象,必须提供无参的构造方法
- Method getMethod(String name,Class… paramType) 获得特定方法
name是方法名, paramType是参数的类型
Method类的方法:
- Object invoke(Object obj,Object… params) 调用方法
obj是调用方法的对象,params是参数的值
调用指定构造方法
Class类的方法:
- Constructor getContructor(Class… paramType) 获得构造方法
paramType是构造方法的参数类型
Constructor的方法:
- Object newInstance(Object… params) 创建对象
params是参数的值
反射案例
案例:运行时获得类的属性和方法信息
class Person{
private String name;
private Integer age;
public Person(){
}
public Person(String name,Integer age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void sayHi(){
System.out.println("Hi:"+name+","+age);
}
}
public class ReflectTest {
public static void main(String[] args){
try {
//获得类型
Class clazz = Person.class;
//获得所有的属性
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields){
//属性名称
String name = f.getName();
//属性类型
Class c = f.getType();
System.out.println(name+" - "+c);
}
//获得所有的方法
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods){
//方法名
String name = m.getName();
//返回值类型
Class returnType = m.getReturnType();
System.out.print(returnType + " " + name + "(");
//参数
Class[] params = m.getParameterTypes();
for(Class c : params){
System.out.print(" " + c.getName());
}
System.out.println(")");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
案例:创建对象,调用方法
try {
//获得类型
Class clazz = Person.class;
//获得类的对象,调用默认的构造方法
Object obj = clazz.newInstance();
//获得对象的方法
Method m1 = clazz.getMethod("setName", String.class);
Method m2 = clazz.getMethod("setAge", Integer.class);
Method m3 = clazz.getMethod("sayHi");
//调用方法
m1.invoke(obj, "micheal");
m2.invoke(obj, 20);
m3.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
案例:调用指定构造方法
try {
//运行时将Person类加载到内存中
Class clazz = Person.class;
//获得指定的构造方法
Constructor con = clazz.getConstructor(String.class,Integer.class);
//调用构造方法
Object obj = con.newInstance("Jim",30);
//调用方法
Method m = clazz.getMethod("sayHi");
m.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
案例:使用反射完成JSON解析
public class JSONUtils{
/**
* 解析JSON,返回Java对象
* @param json JSON字符串
* @param clazz Java类型
* @return Java对象
* @throws Exception
*/
public static Object fromJSON(String json,Class clazz) throws Exception {
Object obj = clazz.newInstance();
//去掉JSON字符串前后{}和"
json = json.replace("{", "").replace("}", "").replace("\"","");
//按,分割字符串
String[] strings = json.split("\\,");
for(String str : strings){
//再按:分割出属性名和属性值
String[] strs = str.split("\\:");
String name = strs[0];
String value = strs[1];
//获得属性
Field field = clazz.getDeclaredField(name);
//修改属性为可以访问,因为是private的
field.setAccessible(true);
Object val = null;
//判断属性类型,转换值的类型
if(field.getType() == Integer.class){
val = Integer.valueOf(value);
}else{
val = value;
}
//属性赋值
field.set(obj,val);
}
//返回对象
return obj;
}
public static void main(String[] args) throws Exception {
String json = "{\"name\":\"张三\",\"age\":\"20\"}";
Person person = (Person) JSONUtils.fromJSON(json,Person.class);
person.sayHi();
}
}
结束
作业:用反射实现Java对象转换为JSON
大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总