# JSON技术和反射
## 1 JSON技术的基础使用
下方代码是利用JSON技术封装了一个JSON工具类,可将对象和JSON类型的字符串相互转换
package cn.itcast.eshop.common.until;
import com.alibaba.fastjson.JSON;
import java.util.List;
/*
* JSON工具类
* 处理和JSON相关的所有内容
* */
public class JSONUtil {
/**
* 将对象转换为JSON格式的字符串
* @param entity 指定对象
* @return 返回JSON格式的字符串
*/
public static String entity2JSON(Object entity) {
return JSON.toJSONString(entity);
}
/**
* 将对象列表转换为JSON格式的字符串
* @param entityList 指定的对象列表
* @return 返回JSON类型的字符串
*/
public static String entityList2JSON(List>entityList) {
return entity2JSON(entityList);
}
/**
* 将JSON类型的字符串转换为指定类型的对象
* ? 泛型的通配符,代表未知的任意类型,或者说是Object类
* @param json 要转换的数据
* @param clazz 指定的类型
* @return 返回Object对象
*/
// public static Object JSON2Entity(String json,Class>clazz) {
// Object obj = JSON.parseObject(json,clazz);
// return obj;
// }
public static T JSON2Entity(String json,Class clazz) {
return JSON.parseObject(json,clazz);
}
/**
* 将JSON数组转换为指定类型的对象列表
* @param json 数据
* @param clazz 指定的类型Class对象
* @param 指定的类型
* @return 对象列表
*/
public static List JSONArray2List(String json,Class clazz) {
return JSON.parseArray(json,clazz);
}
}
## 2 反射
### 2.1 获取字节码文件的三种方式
类加载器(ClassLoader)
负责将类的字节码文件(.class文件)加载到内存中,并生成对应的class对象
Class对象
java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件
**获取Class对象的三种方式**
· Object类的getClass()方法
`Class clazz = 对象名.getClass();`
· 类的静态属性
`Class clazz = 类名.class;`
· Class类的静态方法
`Class clazz = Class.forName("正名");`
//正名:包名+类名 例:cn.itcast.demo01.Student
### 2.2 反射方式获取构造方法并使用
**Constructor
构造器对象,属于java.base模块,java.lang.reflect包
**通过Class对象获取构造器对象**
·getConstructor(Class>...parameterTypes)
返回一个Constructor对象,仅公共构造函数
Class>...:可变参数,代表Class类型的数组
?:通配符,代表不确定的任意类型
package cn.itcast.demo4;
public class Student {
public Student(String s) {
System.out.println("这是一个有参构造"+s);
}
public void shouMenu() {
System.out.println("欢迎使用此方法");
}
}
package cn.itcast.demo4;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) throws Exception {
//创建一个Class对象,获取Student的字节码文件
Class cs = Student.class;
//创建一个构造器对象
Constructor cons = cs.getConstructor(String.class);
//获取构造函数名
String s = cons.getName();
System.out.println(s);
//通过构造器对象构造Student对象
Student s1 = (Student) cons.newInstance("学生");
}
}
·getDeclaredConstructor(Class>...parameterTypes)
返回一个Constructor对象,可获取私有构造函数
//操作方法与上述代码类似
·getConstructors()
返回此类的所有(不含私有)构造函数的数组
//操作与上述类似
**Construct类的常用方法**
·String getName()
//返回构造函数名
·T newInstance(Object...initargs)
//使用此构造函数和指定参数创建并初始化对象
### 2.3 反射方式获取成员方法并使用
**Method对象**
方法对象和构造器对象属于同一模块,同一包下
**通过Class对象获取方法**
·getMethod(String name,Class>...parameterTypes)
返回一个Method对象,仅公共成员方法
name:方法名
parameterTypes:方法的参数列表
package cn.itcast.demo4;
public class Student {
public Student(String s) {
System.out.println("这是一个有参构造"+s);
}
public void shouMenu(String s) {
System.out.println("欢迎使用此方法"+s);
}
}
package cn.itcast.demo4;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
//创建一个Class对象,获取Student的字节码文件
Class cs = Student.class;
//创建一个构造器对象
Constructor cons = cs.getConstructor(String.class);
//通过构造器对象构造Student对象
Student s1 = (Student) cons.newInstance("学生");
//创建一个Method对象(通过Class对象获取)
Method mt = cs.getMethod("shouMenu",String.class);
//调用方法
mt.invoke(s1,"学生");
}
}
·getDeclaredMethod(String,Class>...)
返回一个Method对象,可获取私有方法
·getMethods()
返回此类私有(不含私有)方法的数组
**Method的常用方法**
·String getName()
//返回方法名
·Object invoke(Object obj,Object...args)
//在指定对象上调用此方法,参数为args
### 2.4 反射方式获取成员变量并使用
**Field对象**
域(成员变量、属性)对象,属于java.base模块,java.lang.reflect包
**通过Class对象获取属性**
·getField(String name)
返回一个Filed对象,仅公共属性
name:属性名
·getDeclaredField(String name)
返回一个Field对象,可获取私有属性
package cn.itcast.demo4;
public class Student {
public String name;
private int age;
//重写toString()方法,以便主函数直接打印
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package cn.itcast.demo4;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception {
//创建一个Class对象,获取Student的字节码文件
Class clazz = Student.class;
//创建一个构造器对象
Constructor cons = clazz.getConstructor();
//通过构造器对象构造Student对象
Student s1 = (Student) cons.newInstance();
//创建Field对象
Field field1 = clazz.getField("name");
//设置对象的name属性(公有属性)
field1.set(s1,"张三");
Field field2 = clazz.getDeclaredField("age");
//暴力反射,()内部为true为开启暴力反射,用于访问私有属性和私有方法
field2.setAccessible(true);
//设置对象的age属性(私有)
field2.set(s1,20);
//打印对象,看对象内部值是否被设置成功
System.out.println(s1);
}
}
·getFields()
返回此类所有(不含私有)属性的数组
**Field的常用方法**
·void set(Object obj,Object value)
//设置obj对象的指定属性值value
·void setAccessble(boolean flag)
//将此属性的可访问性设置为指定布尔值(即暴力反射)