1.定义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2.作用
在日常的开发中无外乎两种最常用的用法:
-
操作因访问权限限制的属性和方法;
-
实现自定义注解;
3.反射的四个核心类
-
java.lang.Class.java:类对象;
-
java.lang.reflect.Constructor.java:类的构造器对象;
-
java.lang.reflect.Method.java:类的方法对象;
-
java.lang.reflect.Field.java:类的属性对象;
4.通过反射获取类、属性、方法的基本操作,也是本文的重点
下面我将用代码方式逐步分析反射的具体用法,下文中用到的获取类、属性、构造器的相关方法不太清楚的请参考我的另一篇博客https://blog.csdn.net/Lychee__/article/details/121396023
a.获取Class对象(使用类名.class方式)
(获取Class对象有三种方式,在这里不做具体分析,需要了解的请自行查阅喔)
//获取Class类
Class<Student> aClass = Student.class;
System.out.println("获取到的类为:"+aClass.getName());//输出获取到的类
控制台打印结果为:
b.通过获取的Class类获取目标类的对象(使用getContructor()方法)
Constructor<Student> aClass1Constructor = aClass.getConstructor();
Student student = aClass1Constructor.newInstance();
System.out.println("获取到的对象为:"+student.getName());//输出获取到的对象
c.通过获取的对象获取该类的所有方法(使用getDeclareMethods()方法)
Method[] methods = student.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("获取到的方法有:"+methods[i].getName());
}
for循环遍历并在控制台输出:
c.通过反射获取类中的某个方法并调用该方法(使用getDeclaredMethod()方法)(示例setMobile)
Method setMobile = aClass.getDeclaredMethod("setMobile", String.class);
//通过Modifier.isXXX判断你获取的方法的权限修饰符,正确输出为true,否则为false
System.out.println("method is public:"+
Modifier.isPublic(setMobile.getModifiers()));
//通过getParameterTypes()获取该方法的参数类型
Class<?>[] parameterTypes = setMobile.getParameterTypes();
for (int i = 0; i <parameterTypes.length; i++) {
System.out.println("获取到方法的参数类型为:"+parameterTypes[i].getName());
}
setMobile.invoke(student,"15560695750");
Method getMobile = aClass.getDeclaredMethod("getMobile");
//注解测试
FunctionValidate Validate = new FunctionValidate();
Validate.validate(student);
System.out.println("学生的手机号为:"+Validate.validate(student));
控制台打印结果为:
d.反射获取所有属性(使用getDeclaredFields()方法)
Field[] fields = aClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("获取到该类的属性有:"+fields[i].getName());
}
控制台打印结果为:
e.获取单个属性并进行赋值操作(使用getDeclaredFields()方法、set方法)
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
//Method setName = aClass.getDeclaredMethod("setName", String.class);
name.set(aClass,"小红");
下面附上以上片段总结代码,测试请自取:
Student类Student.java
package com.lychee.annotationStudy.lengthAnnotation;
import com.lychee.annotationStudy.lengthAnnotation.Length;
import com.lychee.annotationStudy.lengthAnnotation.FunctionValidate;
public class Student {
private int id; // 学号
private String name; // 姓名
@Length(min = 11, max = 11, errorMsg = "电话号码的长度必须为11位")
private String mobile; // 手机号码(11位)
public Student() {
}
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 getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
测试类Test.java
package com.lychee.annotationStudy.lengthAnnotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws Exception{
//获取Class类
Class<Student> aClass = Student.class;
System.out.println("获取到的类为:"+aClass.getName());//输出获取到的类
//通过获取的Class类获取目标类的对象
Constructor<Student> aClass1Constructor = aClass.getConstructor();
//aClass1Constructor.setAccessible(true);//反射时访问私有变
Student student = aClass1Constructor.newInstance();
System.out.println("获取到的对象为:"+student.getName());//输出获取到的对象
//通过获取的对象获取类的所有方法
Method[] methods = student.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("获取到的方法有:"+methods[i].getName());
}
//通过反射获取类中的某个方法并调用该方法(示例setMobile)
Method setMobile = aClass.getDeclaredMethod("setMobile", String.class);
//通过Modifier.isXXX判断你获取的方法的权限修饰符,正确输出为true,否则为false
System.out.println("method is public:"+ Modifier.isPublic(setMobile.getModifiers()));
//通过getParameterTypes()获取该方法的参数类型
Class<?>[] parameterTypes = setMobile.getParameterTypes();
for (int i = 0; i <parameterTypes.length; i++) {
System.out.println("获取到方法的参数类型为:"+parameterTypes[i].getName());
}
setMobile.invoke(student,"15560695750");
Method getMobile = aClass.getDeclaredMethod("getMobile");
System.out.println("学生的手机号为:"+student.getMobile);
//反射获取所有属性
Field[] fields = aClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("获取到该类的属性有:"+fields[i].getName());
}
//获取单个属性并进行赋值操作
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
//Method setName = aClass.getDeclaredMethod("setName", String.class);
name.set(aClass,"小红");
}
}
以上就是本次Java反射具体实现的全部内容了,具体个人理解还需读者自行思考,如有指正请联系我,感谢阅读。