【主要内容】
-
反射的概念
-
Java类加载的三个阶段
-
Class、Field、Constructor、Method类详解
-
注解的概述
-
元注解
-
自定义注解
-
类加载器
-
泛型擦除问题
【学习目标】
知识点 | 要求 |
---|---|
反射的概念 | 掌握 |
Java类加载的三个阶段 | 掌握 |
Class、Field、Constructor、Method类详解 | 掌握 |
注解的概述 | 掌握 |
元注解 | 掌握 |
自定义注解 | 掌握 |
类加载器 | 掌握 |
泛型擦除问题 | 掌握 |
1. 反射
1.1 【掌握】反射概念和功能
1.1.1 概念
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
说人话,反射机制就是将类的各个组成部分(属性,方法,构造器)封装为其它对象。
如图所示:
举例说明:
在IDEA中展示的Student.class文件看到的不是乱码!
原因是: IDEA中后台已经通过反射将Student.class文件进行就反编译。
1.1.2 反射提供的功能
在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
1,反编译:.class-->.java
2,通过反射机制访问java对象的属性,方法,构造方法,注解等;
1.1.3 反射的相关类
java.lang.Class; java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.lang.reflect.Modifier; 权限修饰符事物描述类
1.2 【掌握】Java类加载的三个阶段
1.2.1 源代码(source)
源代码不是指.java文件,而是经编译器编译后生成的.class字节码文件
1.2.2 类加载(class)
class字节码文件经类加载器classloader加载到虚拟机内存。类加载器解析class文件生成Class类型的对象
1.2.3 运行时(runtime)
newInstance()根据java类型生成对象
1.2.4 图解
1.3 【掌握】获取Class的三种方式
1.3.1 概述
Class对象的三种获取方式对应上面Java类加载的三个阶段
1.3.2 准备工作创建Student
/* @Author yangge @Date 2023/8/17 @Description 学生类 */ public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
1.3.3 反射机制获取类有三种方法,我们来获取Student类型
/* @Author yangge @Date 2023/8/17 @Description 反射机制获取类有三种方法,我们来获取Student类型 */ public class RefleDemo2 { public static void main(String[] args) throws ClassNotFoundException { // 方式一: Class clazz1 = Class.forName("com.huayu.reflection.demo1.Student"); System.out.println("clazz1 = " + clazz1);//clazz1 = class com.huayu.reflection.demo1.Student // 方式二:任何类都有class属性 Class<Student> clazz2 = Student.class; System.out.println("clazz2 = " + clazz2); // 方式三:任何对象都有getClass()方法 Student student = new Student(); Class clazz3 = student.getClass(); System.out.println("clazz3 = " + clazz3); } }
注意事项: Class.forName("com.huayu.reflection.demo1.Student") 1. 在java中表示路径时使用.连接各个包 , 而在进行IO操作时,使用 / 或者 \\ 连接各个包 2. 使用类加载器读字节码文件时,默认从src包中读, 而且读取时使用类的全类名 3. 三种方式获得的类对象是同一个对象,一个类文件只对应一个类对象。
1.4 【掌握】Class的功能
1.3.1 获取功能
1.3.1.1 获取成员变量
Field | getField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段类对象。 |
---|---|
Field[] | getFields() 返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段类对象。 |
Field | getDeclaredField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定已声明字段类对象。 |
Field[] | getDeclaredFields() 返回的数组 Field对象反映此表示的类或接口声明的所有字段类对象。 |
代码如下:
package com.huayu.reflection.demo2; import java.lang.reflect.Field; /* @Author yangge @Date 2023/8/17 @Description 获取字节码中的成员变量 明确: 一个Class对象就是一个.java 或者 .class文件, 里面封装了java类的属性,成员方法,构造方法等各个信息 getField(String name) : 根据属性名称获取公有属性 getFields() : 获取所有公有属性 getDeclaredField(String name) : 根据名称获取属性(公有,私有均可) getDeclaredFields() :获取所有属性(公有,私有均可) */ public class RefleDemo1 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { // 1. 获得Student类对象, 或者说是Student.java文件 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); // 2. 获取Student.java文件中的公有属性:name Field nameField = aClass.getField("name"); System.out.println("nameField = " + nameField); // 3. 获取Student.java文件中的所有的公有属性:name , score Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("--------------------------------"); // 4. 获取Student.java文件中的私有属性:age Field ageField = aClass.getDeclaredField("age"); System.out.println("ageField = " + ageField); System.out.println("--------------------------------"); // 5. 获取Student.java文件中所有的公有和私有属性:age,school Field[] declaredFields = aClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } } }
1.3.1.2 获取构造方法
Constructor<T> | getConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共类函数 |
---|---|
Constructor<?>[] | getConstructors() 返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造类对象。 |
Constructor<T> | getDeclaredConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定类函数。 |
Constructor<?>[] | getDeclaredConstructors() 返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组类 。 |
代码如下:
/* @Author yangge @Date 2023/8/17 @Description 获取构造方法对象 Constructor<T> getConstructor(类<?>... parameterTypes) :根据参数类型返回对应的公共构造方法对象 Constructor<?>[] getConstructors() :返回所有公共构造方法对象,存入构造方法对象数组 Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) : 根据参数类型返回对应的构造方 法对象(公有和私有均可) Constructor<?>[]getDeclaredConstructors() : 返回所有的构造方法对象,存入构造方法对象数组(公有和私 有均可) 注意事项: int类型的字节码: int.class Integer类型的字节码:Integer.class */ public class RefleDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { // 1. 获取Student字节码对象 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); // 2. 获取公有的无参构造 Constructor cons1 = aClass.getConstructor(); System.out.println("cons1 = " + cons1); // 3. 获取公有的满参构造 Constructor cons2 = aClass.getConstructor(String.class, int.class, int.class, String.class); System.out.println("cons2 = " + cons2); System.out.println("------------------------------------"); // 4. 获取所有的公共的构造方法 Constructor[] conss = aClass.getConstructors(); for (Constructor constructor : conss) { System.out.println(constructor); } System.out.println("------------------------------------"); // 5. 获取2个参数的私有的构造方法 Constructor dcons1 = aClass.getDeclaredConstructor(String.class, int.class); System.out.println("dcons1 = " + dcons1); System.out.println("------------------------------------"); // 6. 获取所有的构造方法 Constructor[] declaredConstructors = aClass.getDeclaredConstructors(); for (Constructor declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } } }
1.3.1.3 获取成员方法
Method | getMethod(String name, 类<?>... parameterTypes) 返回一个 方法对象,它反映此表示的类或接口的指定声明的方法类对象。 |
---|---|
Method[] | getMethods() 返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法类对象,包括那些由类或接口和那些从超类和超接口继承的声明。 |
Method | getDeclaredMethod (String name, 类<?>... parameterTypes)返回一个 方法对象,它反映此表示的类或接口的指定声明的方法类对象。 |
Method[] | getDeclaredMethods 返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。 |
代码如下:
/* @Author yangge @Date 2023/8/17 @Description 获取方法对象 Method getMethod(String name, 类<?>... parameterTypes) : 根据方法名和参数类型获得对应的公共方法对象 Method[] getMethods() : 获取所有的公共的方法对象,存入数组 Method getDeclaredMethod(String name, 类<?>... parameterTypes):根据方法名和参数类型获得对应的方法对象(公有和私有) Method[] getDeclaredMethods():获取所有的方法对象,存入数组(公有和私有) */ public class RefleDemo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { // 1. 获取Student的字节码对象 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); // 2. 分别获得getName() 和setName() 对象 Method getName = aClass.getMethod("getName"); Method setName = aClass.getMethod("setName", String.class); System.out.println("getName = " + getName); System.out.println("setName = " + setName); System.out.println("-----------------------------"); //3. 获取所有的公有的方法对象 : aClass.getMethods() : 把父类Object中继承过来的也获取了 Method[] methods = aClass.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("-----------------------------"); // 4. 分别获取私有的getAge() , setAge() 对象 Method getAge = aClass.getDeclaredMethod("getAge"); Method setAge = aClass.getDeclaredMethod("setAge", int.class); System.out.println("getAge = " + getAge); System.out.println("setAge = " + setAge); System.out.println("-----------------------------"); // 5. 获取所有的方法对象 : 无法获取父类Object中的方法,只能获取当前类中公有和私有方法 Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } } }
总结:
getXFields() , getMethods() ,getConstructors(): 获取当前类以及父类中所有公共的方法 getXDeclaredFields() , getDeclaredMethods() ,getDeclaredConstructors(): 获取当前类中所有方法,包括共有和私有,但是无法获取从父类继承的
1.3.1.4 获取类名
String | getName(): 返回由 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String 。 |
---|---|
String | getSimpleName(): 返回源代码中给出的基础类的简单名称。 |
代码如下:
/* @Author yangge @Date 2023/8/17 @Description 获取类名 String getName() : 获取类的全类型名称 : 包名 + 类名 String getSimpleName() : 获取类的简单名称 : 类名 */ public class RefleDemo4 { public static void main(String[] args) throws ClassNotFoundException { // 1. 获取Student类对象 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); //2. 获取aclass类对象的全类型名称 String name = aClass.getName(); System.out.println("name = " + name);//name = com.huayu.reflection.demo1.Student // 3. 获取aclass类对象的简单简单名称 String simpleName = aClass.getSimpleName(); System.out.println("simpleName = " + simpleName);//simpleName = Student } }
1.3.2 Field成员变量相关方法
Object | get(Object obj) 获取obj对象的对应的field对象属性对应的属性值 |
---|---|
int | getModifiers() 返回由该 Field对象表示的字段的Java语言修饰符,作为整数。 |
String | getName() 返回由此 Field对象表示的字段的名称。 |
类<?> | getType() 返回由此 Field对象对应属性的类型 |
void | set(Object obj, Object value) 将obj对象的对应的field对象属性值修改为:value |
void | setAccessible(boolean flag) 打开暴力访问开关 |
代码示例:
package com.huayu.reflection.demo2; import com.huayu.reflection.demo1.Student; import java.lang.reflect.Field; import java.lang.reflect.Type; /* @Author yangge @Date 2023/8/17 @Description int getModifiers 返回由该 Field对象表示的字段的Java语言修饰符,作为整数。 String getName() 返回由此 Field对象表示的字段的名称。 类<?>getType() 返回由此 Field对象对应属性的类型 Object get(Object obj) 获取obj对象的对应的field对象属性对应的属性值 void set(Object obj, Object value): 将obj对象的对应的field对象属性值修改为:value void setAccessible(boolean flag) :打开暴力访问开关 注意事项: 1. 只有getDeclaredField()才能访问私有属性,并且要打开暴力访问开关才能获取对应的私有属性值 */ public class RefleDemo5 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { // 1. 获取Student.java文件 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); //2. 获得age属性对象 Field ageField = aClass.getDeclaredField("age"); // 3. 获取该属性对象的权限修饰符 int modifiers = ageField.getModifiers();// private : 2 ,public : 1 ,protected : 4 , default : 0 , static : 8 System.out.println("modifiers = " + modifiers); //4. 获取该属性对象的类型 Class type = ageField.getType(); System.out.println("type = " + type);//type = int //5. 获取该属性对象的名称 String name = ageField.getName(); System.out.println("name = " + name);//name = age // 6. 获取该属性对象的属性值 ageField.setAccessible(true); int o = (int) ageField.get(new Student("张三", 25, 99, "华育大学")); System.out.println("o = " + o); // 7. 修改当前对象的,这个age属性的值为:30 Student stu = new Student("张三", 25, 99, "华育大学"); ageField.set(stu,30); int o1 = (int) ageField.get(stu); System.out.println("o1 = " + o1); // 8. 获取school属性对象 Field schoolField = aClass.getDeclaredField("school"); // 打开暴力访问开关 schoolField.setAccessible(true); // 获取学生对象的私有属性school的值 String o2 = (String) schoolField.get(new Student("张三", 25, 99, "华育大学")); System.out.println("o2 = " + o2); } }
1.3.3 Constructor成员变量相关方法
int | getModifiers() 返回构造方法的权限修饰符 |
---|---|
String | getName() 以字符串形式返回此构造函数的名称。 |
int | getParameterCount() 返回构造方法对象中参数的个数。 |
Class<?>[] | getParameterTypes() 按照顺序将构造方法的参数类型存入数组中并返回 |
void | setAccessible(boolean flag) 打开暴力访问开关 |
T | newInstance(Object... initargs) 执行该构造方法对象并创建实例化对象 |
代码如下:
/* @Author yangge @Date 2023/8/20 @Description int getModifiers() 返回构造方法的权限修饰符的魔法值 String getName() 以字符串形式返回此构造函数的名称。 int getParameterCount() 返回构造方法对象中参数的个数。 Class<?>[] getParameterTypes() 按照顺序将构造方法的参数类型存入数组中并返回 void setAccessible(boolean flag) 打开暴力访问开关 T newInstance(Object... initargs):执行该构造方法对象并创建实例化对象 */ public class RefleDemo6 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { // 1. 获取Student.java类文件 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); //2. 获取构造方法对象 Constructor constructor = aClass.getDeclaredConstructor(String.class, int.class, int.class, String.class); //3. 获取该构造方法的权限修饰符魔法值 int modifiers = constructor.getModifiers(); System.out.println("modifiers = " + modifiers);//modifiers = 1 //4. 获取该构造方法的名称 String name = constructor.getName(); System.out.println("name = " + name);//name = com.huayu.reflection.demo1.Student //5. 获取该构造方法的形参的个数 int parameterCount = constructor.getParameterCount(); System.out.println("parameterCount = " + parameterCount);//parameterCount = 4 //6. 获取该构造方法的形参的类型并按照顺序存入数组 Class[] parameterTypes = constructor.getParameterTypes(); for (Class parameterType : parameterTypes) { System.out.println(parameterType); } // 7. 执行该构造方法对象并创建实例化对象 // 打开暴力访问开关 constructor.setAccessible(true); Student stu = (Student) constructor.newInstance("zhangsan", 18, 95, "华育大学"); System.out.println("stu = " + stu); } }
1.3.4 Method成员变量相关方法
int | getModifiers() : 获取成员方法的权限修饰符魔法值 |
---|---|
String | getName() 返回由此 方法对象表示的方法的名称,作为 String 。 |
int | getParameterCount() 返回由此方法对象的参数个数。 |
类<?>[] | getParameterTypes() 返回该方法对象的形式参数类型并按照顺序存入数组中。 |
类<?> | getReturnType() 返回该方法对象的返回值类型 |
Object | invoke(Object obj , Object ... args) 执行obj对象的该方法对象并使用实参args |
代码示例:
/* @Author yangge @Date 2023/8/20 @Description int getModifiers() : 获取成员方法的权限修饰符魔法值 String getName()返回由此 方法对象表示的方法的名称,作为 String 。 int getParameterCount()返回由此方法对象的参数个数。 类<?>[]getParameterTypes() 返回该方法对象的形式参数类型并按照顺序存入数组中。 类<?> getReturnType() 返回该方法对象的返回值类型 Object invoke(Object obj , Object ... args) 执行obj对象的该方法对象并使用实参args */ public class RefleDemo7 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { //1. 获取Student.java文件 Class aClass = Class.forName("com.huayu.reflection.demo1.Student"); //2. 获取equals方法对象 Method setAgeMethod = aClass.getDeclaredMethod("setAge", int.class); //3. 获取setAgeMethod的权限修饰符魔法值 int modifiers = setAgeMethod.getModifiers(); System.out.println("modifiers = " + modifiers); //4. 获取setAgeMethod方法对象的返回值类型 Class<?> returnType = setAgeMethod.getReturnType(); System.out.println("returnType = " + returnType.getName()); //5. 获取方法名 String name = setAgeMethod.getName(); System.out.println("name = " + name);//name = setAge //6. 获取参数个数 int parameterCount = setAgeMethod.getParameterCount(); System.out.println("parameterCount = " + parameterCount); // 7. 获取参数类型并按照顺序存入数组 Class<?>[] parameterTypes = setAgeMethod.getParameterTypes(); for (Class<?> parameterType : parameterTypes) { System.out.println(parameterType.getName()); } //8. 执行该方法 // 打开暴力访问开关 setAgeMethod.setAccessible(true); Student stu = new Student(); setAgeMethod.invoke(stu, 20); // 获取stu对象的age值 Method getAgeMethod = aClass.getDeclaredMethod("getAge"); getAgeMethod.setAccessible(true); int invoke = (int) getAgeMethod.invoke(stu); System.out.println("invoke = " + invoke); } }
1.5 【案例】写一个框架
1.5.1 需求
写一个框架,不能改变类的任何代码的前提下,可以帮我们创建任意类的对象,并执行其中任意方法
1.5.2 实现
-
配置文件
-
反射
1.5.3 步骤
-
将需要创建的对象的全类名和需要执行的方法定义在配置文件中
-
在程序加载读取配置文件
-
使用反射加载类文件进内存
-
创建对象
-
执行方法
1.5.4 创建User类
/* @Author yangge @Date 2023/8/20 @Description 定义用户类实体类 */ public class User { private String name; private int age; private String address; public User() { } public User(String name, int age, String address) { this.name = name; this.age = age; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (name != null ? !name.equals(user.name) : user.name != null) return false; return address != null ? address.equals(user.address) : user.address == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; result = 31 * result + (address != null ? address.hashCode() : 0); return result; } }
1.5.5 创建pro.properties
className=com.huayu.reflection.demo2.User methodName=toString
注意:要将pro.properties文件放置在resources包下,并将resources包设置为项目资源包
1.5.6 写代码
/* @Author yangge @Date 2023/8/20 @Description 读取配置文件pro.properties创建User对象并执行toString方法 */ public class RefleDemo8 { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { // 需求:使用类加载器读取配置文件pro.properties中的配置信息并存入Properties集合中 //1. 获得当前类文件的类加载器并读取pro.properties文件中内容到流中 ClassLoader classLoader = RefleDemo8.class.getClassLoader(); InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties"); //2. 将resourceAsStream流中的内容存入到Properties集合中 Properties properties = new Properties(); properties.load(resourceAsStream); //3. 根据全类名获取类文件对象 String className = (String) properties.get("className"); Class aClass = Class.forName(className); //4. 根据类文件来创建实例化对象 User user = (User) aClass.newInstance(); user.setName("jack"); // 5. 获取要执行的方法名,根据要执行的方法名获取方法对象并调用 String methodName = (String) properties.get("methodName"); Method declaredMethod = aClass.getDeclaredMethod(methodName); //6. 执行该user对象中的declaredMethod方法 System.out.println(declaredMethod.invoke(user)); } }
1.6 自定义一个JSON生成Json串
1.6.1 创建User类
/* @Author yangge @Date 2023/8/20 @Description 定义用户类实体类 */ public class User { private String name; private int age; private String address; public User() { } public User(String name, int age, String address) { this.name = name; this.age = age; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (name != null ? !name.equals(user.name) : user.name != null) return false; return address != null ? address.equals(user.address) : user.address == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; result = 31 * result + (address != null ? address.hashCode() : 0); return result; } }
1.6.2 创建JSON类
/* @Author yangge @Date 2023/8/20 @Description 把简单对象转成json字符串 */ public class RefleDemo9 { private RefleDemo9() { } // 将简单对象User user转成json字符串 public static String toJsonObject(User user) throws IllegalAccessException { // user = {"name":"jack","age":18} StringBuilder sb = new StringBuilder(); sb.append("{"); // 1. 获取user的字节码对象 Class aClass = user.getClass(); // 2. 获取aClass中所有的属性对象 Field[] declaredFields = aClass.getDeclaredFields(); // 3. 遍历declaredFields 获取每一个field对象 for (Field declaredField : declaredFields) { // 4. 获取declaredField 名称作为key String fieldName = declaredField.getName(); // 5. 获取declaredField 属性值作为:value declaredField.setAccessible(true); Object fieldValue = declaredField.get(user); if (fieldValue instanceof String || fieldValue instanceof StringBuffer || fieldValue instanceof StringBuilder){ fieldValue = "\""+ fieldValue+"\""; } // 6. 将键值对拼接到sb中 sb.append("\""+fieldName+"\"" +":"+fieldValue+","); } // 将最后的 , 去掉 sb.replace(sb.length()-1, sb.length(), ""); sb.append("}"); return sb.toString(); } public static void main(String[] args) throws IllegalAccessException { User user = new User("jack", 18, "武汉"); String s = toJsonObject(user); System.out.println("s = " + s); } }