java中的反射的简单应用
1.反射的作用:
反射主要应用在程序执行中,为了动态获得一个类或对象的变量、构造方法、成员方法等并在程序运行中动态创建对象,调用对象的方法和访问变量
以以下代码为例,代码中省略了get/set和toString方法:
import java.util.Arrays;
public class Reflect {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
//以下打印功能和代码放置位置
}
}
class Student{
private String name;
public int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
private void method(){
System.out.println("私有方法");
}
public void print(Student student){
System.out.println(student.name);
}
}
2.获取class类
用到的是java.lang下的Class类,Class 类的实例表示正在运行的 Java 应用程序中的类和接口
以下三种方式获得的是相同的类
方式1:
Student student = new Student();
class clazz = student .getClass;
方式2:
class clazz = Student .getClass;
方式3:
这种方式因为传入了路径,所以程序会让抛出异常或者用try/catch处理
Class clazz = Class.forName("com.test.Student");;
3.获取class类名
clazz.getName();
>>>com.test.Student
4.获取类中的变量/字段
clazz.getFiled(String name);
返回的是单个变量
System.out.println(clazz.getField("age"));
>>>public int com.test.Student.age
clazz.getFileds()
返回的是此类及父类中的公共变量,是一个数组
clazz.getDeclaredField(String name)
返回的是单个变量,但可以返回私有变量
clazz.getDeclaredFields()
返回自己的所有成员变量,不包含父类
System.out.println(Arrays.asList(clazz.getDeclaredFields()));
>>>[private java.lang.String com.test.Student.name, public int com.test.Student.age]
5.获取对象的构造方法
getConstructors()
获取的是此类中定义的公共构造方法
getDeclaredConstructors()
获取的是此类中所有的构造方法
这里去掉最后的s,并指定参数可以获得特定的构造方法
如果想要获取特定的构造方法:
5.1 无参的构造方法
getConstructors(null)
获取的是此类中定义的公共构造方法
5.2获取特定需要传入两个参数的构造方法
这里参数的后面要加.class
,涉及到Class类,不做深入探讨
getConstrucors(String.class,int.class)
这里打印以下构造方法的名称,
System.out.println(clazz.getConstructor(String.class,int.class).getName());
>>>com.test.Student
显示这个构造方法的具体信息
System.out.println(clazz.getConstructor(String.class,int.class).toString());
>>>public com.test.Student(java.lang.String,int)
6.获取对象的成员方法
返回类型是Method类
getMethod("方法名",参数类.class)
返回需要传入参数的方法
System.out.println(clazz.getDeclaredMethod("print", Student.class));
getMethods()
这里传回的包含父类公共方法
getDeclaredMethods()
返回自己的所有方法,这里不包含构造方法
System.out.println((Arrays.asList(clazz.getDeclaredMethods())));
>>>[private void com.test.Student.method()]
7.操作对象
7.1创建对象
主要类:Class
无参的构造方法创建:
Class clazz = Object.class;
Object o = clazz.newInstance();
如果想要创建想要的类,将Object替换成想要的类,并进行强转:
Class clazz = Student.class;
Student s =(Student) clazz.newInstance();
有参的构造方法
Class clazz = Object.class;
Constructor constructor = clazz.getDeclaredconstructor(Sting.class,int.class);
Object zs = constructor.newInstance("张三",20);
Class clazz = Student.class;
Constructor constructor = clazz.getDeclaredConstructor(String.class , int.class);
Student s =(Student) constructor.newInstance("张三",20);
System.out.println(s.toString());
>>> Student{name='张三', age=20}
7.2 获取成员变量并对新建的对象设置变量
主要类:Field
对于public公有的变量age:
借助Field对象进行设置,这里调用get/set方法是Field类的
Class clazz = Student.class;
Object student = clazz.newInstace();
Field age = clazz.getDeclaredFiled("age");
age.set(student,25);
System.out.println(student);
>>> Student{name='null', age=25}
对于private私有的变量name,这里需要先进行暴力反射:
Class clazz = Student.class;
Object student = clazz.newInstace();
Field name = clazz.getDeclaredFiled("name");
name.setAccessible(true);
name.set(student,"lisi");
System.out.println(student);
>>> Student{name='lisi', age=0}
7.3 获取成员方法
主要类:Method
- 拿到类
Class studentClazz = Student.class
- 创建对象
Constructor constructor = studentClazz.getDeclaredConstructor(String.class,int.class);
Student student = (Student) constructor.newInstance("赵六",30);
- 获取方法
Method print = studentClazz.getDeclaredMethod("print",Student.class);
对于私有方法,先设置暴力反射
print.setAccessible(true);
- 执行方法
Object invoke = print.invoke(student,student);
8.完整代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Fanshe {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//获取类
Class studentClazz = Student.class;
//获取构造方法
Constructor constructor = studentClazz.getDeclaredConstructor(String.class,int.class);
//实例化类对象
Student student = (Student) constructor.newInstance("赵六",30);
//获取类的方法
Method print = studentClazz.getDeclaredMethod("print");
//传入实例对象调用方法
Object invoke = print.invoke(student);
}
}
class Student extends People{
private String name;
public 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;
}
private void method(){
System.out.println("私有方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void print(){
System.out.println(this.name);
}
}
class People{
public void method1(){
System.out.println("父类方法");
}
}
9.用到的类总结:
- Class 获取类,使用任何对象的
.class属性
- Constructor 获取类的构造方法,用
newInstance()
实例化对象 - Field 类的成员变量,set/get用来设置和获取实例对象的成员变量的值
- Method 类的成员方法,
.invoke()
调用拿到的方法