|
# 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> T JSON2Entity(String json,Class<T> clazz) {
? ? ? ? return JSON.parseObject(json,clazz);
? ? }
? ? /**
? ? ?* 将JSON数组转换为指定类型的对象列表
? ? ?* @param json 数据
? ? ?* @param clazz 指定的类型Class对象
? ? ?* @param <T> 指定的类型
? ? ?* @return 对象列表
? ? ?*/
? ? public static <T> List<T> JSONArray2List(String json,Class<T> 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<T>对象**
构造器对象,属于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)
? ?//将此属性的可访问性设置为指定布尔值(即暴力反射)
? ?
|