文章目录
1、定义
java反射机制是说:在运行状态中,对于任意的一个类,我们都能知道它的所有属性和方法;对于任意的一个对象,我们都能够调用它的所有方法和得到所有属性。这种动态调用方法和动态获取属性的功能成为java语言的反射机制。
实际上,我们创建的每一个类都是Class对象,称之为类对象。
2、反射机制的方法
//创建一个类
package reflex;
public class Student {
private int id;
private String name;
private String gender;
private String address;
public Student(){
}
public Student(String name){
this.name = name;
}
private Student(String name, String address){
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
1)、获取类对象
package reflex;
import org.junit.Test;
public class ReflexTest {
//获取类对象
@Test
public void m1() throws ClassNotFoundException {
//方法一
Student student = new Student();
System.out.println(student.getClass());
//方法二
String className = "reflex.Student";
System.out.println(Class.forName(className));
}
}
//输出结果
class reflex.Student
class reflex.Student
2)、获取类成员
获取类的构造方法
//获取类的所有public类型的构造方法
@Test
public void m2(){
Student student = new Student();
Class c = student.getClass();
//获取类的所有构造方法
Constructor[] constructors = c.getDeclaredConstructors();
/**
* 通过getDeclaredConstructors方法可以返回类的构造方法,返回的是一个数组
* 通过getModifiers可以得到构造方法的类型,返回的是数字,1-public 2-private
* 通过getParameterTypes可以得到某构造方法的所有参数类型
*/
for(int i = 0;i < constructors.length;++i){
System.out.print(Modifier.toString(constructors[i].getModifiers()) + " " + "参数:"); //获取构造方法的类型
Class[] parameterTypes = constructors[i].getParameterTypes(); //获取构造方法的参数类型
for(int j = 0 ;j < parameterTypes.length;++j){
System.out.print(parameterTypes[j].getName()+ " ");
}
System.out.println("");
}
}
//运行结果
private 参数:java.lang.String java.lang.String
public 参数:java.lang.String
public 参数:
获取类的特定的构造方法
//返回特定的构造方法
@Test
public void m3() throws NoSuchMethodException {
Student stu = new Student();
Class[] c = {String.class,String.class};
Constructor constructor = stu.getClass().getConstructor(c);
System.out.print(Modifier.toString(constructor.getModifiers()) + " " + "参数:");
Class[] parameterTypes = constructor.getParameterTypes();
for(int j = 0 ;j < parameterTypes.length;++j){
System.out.print(parameterTypes[j].getName()+ " ");
}
System.out.println("");
}
//运行结果
public 参数:java.lang.String
//调用构造方法
//调用构造方法
@Test
public void m4() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Student stu = new Student();
//调用公有构造函数
Class[] c1 = {String.class};
Constructor constructor1 = stu.getClass().getDeclaredConstructor(c1);
constructor1.newInstance("yanjundong");
//调用私有构造函数
Class[] c2 = {int.class,String.class};
Constructor constructor2 = stu.getClass().getDeclaredConstructor(c2);
constructor2.setAccessible(true); //多出的一步
constructor2.newInstance(1001,"yanjundong");
}
//运行结果
该学生的姓名为yanjundong
该学生的姓名为yanjundong学号为1001
调用类的私有方法
//调用类的私有方法
@Test
public void m5() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Student stu = new Student();
Class[] p = {String.class};
//通过getDeclaredMethod方法获取这个私有方法,第一个参数为方法名,第二个为参数类型
Method method = stu.getClass().getDeclaredMethod("welcome", p);
method.setAccessible(true);
//通过invoke方法执行,第一个参数为类的实例,第二个参数为方法参数
Object args[] = {"java反射测试"};
method.invoke(stu,args);
}
//运行结果
java反射测试
调用类的私有字段,并修改值
//调用类的私有字段,并修改值
@Test
public void m6() throws NoSuchFieldException, IllegalAccessException {
Student stu = new Student();
stu.setId(1000);
stu.setName("yanjundong");
stu.setAddress("陕西省西安市");
Field field = stu.getClass().getDeclaredField("name");
field.setAccessible(true);
field.set(stu,"yan俊东");
String name = field.get(stu).toString();
System.out.println(name);
}
//运行结果
yan俊东
3、Fastjson
–还是爸爸的产品好用,简单、方便,虽然网上有人说没有Jackson稳定,
//添加maven依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
将Java对象转化为JSON字符串
@Test
public void m3() throws IOException {
Student student = new Student();
student.setId(1000);
student.setAddress("XXXXXXXX");
student.setName("zhangsan");
student.setGender("M");
student.setDate(new Date());
String jsonString = JSON.toJSONString(student);
System.out.println(jsonString);
}
//输出结果
{"address":"XXXXXXXX","date":1571925626901,"gender":"M","id":1000,"name":"zhangsan"}
将JSON字符串转化为Java对象
@Test
public void m3() throws IOException {
Student student = new Student();
student.setId(1000);
student.setAddress("XXXXXXXX");
student.setName("zhangsan");
student.setGender("M");
student.setDate(new Date());
//序列化
String jsonString = JSON.toJSONString(student);
System.out.println(jsonString);
//反序列化
Student student1 = JSON.parseObject(jsonString,Student.class);
System.out.println(student1);
}
//输出结果
{"name":"zhangsan","gender":"M","birthday":"2019-10-24","address":"XXXXXXXX"}
Student{id=0, name='zhangsan', gender='M', address='XXXXXXXX', date=Thu Oct 24 00:00:00 CST 2019}
注解符的使用
@JSONField(serialize=false)
private int id;
@JSONField(ordinal = 1)
private String name;
@JSONField(ordinal = 2)
private String gender;
@JSONField(ordinal = 4)
private String address;
@JSONField(format="yyyy-MM-dd",name = "birthday",ordinal = 3)
private Date date;
//可以使用serialize指定字段不序列化,使用deserialize指定字段不反序列化
//format参数用于格式化date属性
//使用ordinal可以指定字段的顺序
使用 ContextValueFilter 配置 JSON 转换
实现对value的过滤,
@Test
public void m4(){
Student student = new Student();
student.setId(1000);
student.setAddress("XXXXXXXX");
student.setName("zhangsan");
student.setGender("M");
student.setDate(new Date());
ContextValueFilter valueFilter = new ContextValueFilter() {
@Override
public Object process(BeanContext beanContext, Object o, String name, Object value) {
if (name.equals("gender")) {
return "NOT TO DISCLOSE";
}
if (value.equals("zhangsan")) {
return ((String) value).toUpperCase();
}else{
return value;
}
}
};
String jsonOutput = JSON.toJSONString(student, valueFilter);
System.out.println(jsonOutput);
}
//输出结果
{"name":"ZHANGSAN","gender":"NOT TO DISCLOSE","birthday":"2019-10-25","address":"XXXXXXXX"}
使用 NameFilter 和 SerializeConfig
NameFilter
序列化时修改key;
SerializeConfig
内部是个map容器主要功能是配置并记录每种Java类型对应的序列化类;
@Test
public void m5(){
List<Student> studentList = new ArrayList<Student>();
Student student = new Student();
student.setId(1000);
student.setAddress("XXXXXXXX");
student.setName("zhangsan");
student.setGender("M");
student.setDate(new Date());
studentList.add(student);
Student student1 = new Student();
student1.setId(1001);
student1.setAddress("XXXX-XXXX");
student1.setName("lisi");
student1.setGender("W");
student1.setDate(new Date());
studentList.add(student1);
//使用NameFilter过滤器处理字段名称
NameFilter formatName = new NameFilter() {
@Override
public String process(Object o, String name, Object value) {
if("address".equals(name))
return "address of home";
else
return name;
}
};
// 新创建的过滤器与Student类相关联,然后添加到全局实例,它是SerializeConfig类中的静态属性。
SerializeConfig.getGlobalInstance().addFilter(Student.class, formatName);
//使用toJSONStringWithDateFormat而不是toJSONString,它可以更快速的格式化日期。
String jsonString = JSON.toJSONStringWithDateFormat(studentList, "yyyy-MM-dd");
//String jsonString = JSON.toJSONString(studentList);
System.out.println(jsonString);
}
//输出结果
[
{
"address of home": "XXXXXXXX",
"date": 1583304236873,
"gender": "M",
"id": 1000,
"name": "zhangsan"
},
{
"address of home": "XXXX-XXXX",
"date": 1583304236873,
"gender": "W",
"id": 1001,
"name": "lisi"
}
]
来源:CSDN
作者:不知道改什么昵称
链接:https://blog.csdn.net/weixin_40971059/article/details/104653652