这里写目录标题
背景
由于在公司自研的新项目架构中使用了大量的反射来提高项目的可复用、灵活性。
项目运用的场景有:
1.程序运行期间动态生成类并进行调用
2.通过反射时间接口的高复用
趁着这个机会博主对反射的基本应用进行汇总和总结。
一、为什么要使用反射?
反射是一项强大的功能。
- 它允许你在运行时动态操作类、对象、方法和属性
- 它允许你访问类的私有属性和私有方法
二、反射的应用
反射常用应用的思维导图
2.1获取class对象的三种方法
- Class.forName("全限定类名")
- 类名.class
- 对象.getClass();
全限定类名=该类所处的包路径+类名
示例代码
Student类
java
package com.wangwei.myreflec1;
public class Student {
private String name;
private int 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;
}
}
Demo1类
java
package com.wangwei.myreflec1;
public class Demo1 {
/*
获取class对象的三种方式
1.Class.forName("全限定类名")
2.类名.class
3.对象.getClass();
*/
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.wangwei.myreflec1.Student");
System.out.println(aClass);
Class<Student> aClass1 = Student.class;
System.out.println(aClass1);
Student student = new Student();
Class<? extends Student> aClass2 = student.getClass();
System.out.println(aClass==aClass1);
System.out.println(aClass1==aClass2);
}
}
运行结果
2.2利用反射获取构造方法
示例代码
Student类
java
package com.wangwei.myreflect2;
public class Student {
public Student(){
}
public Student (String name){
this.name=name;
}
private Student(int age){
this.age=age;
}
protected Student(String name,int age){
this.name=name;
this.age=age;
}
private String name;
private int 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;
}
}
Demo2类
java
package com.wangwei.myreflect2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 通过反射获取构造方法
*/
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取class字节码文件对象
Class<?> aClass = Class.forName("com.wangwei.myreflect2.Student");
//2.获取构造方法
// Constructor<?>[] constructors = aClass.getConstructors();
// for (Constructor con:constructors){
// System.out.println(con);
// }
// Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
// for (Constructor con:declaredConstructors){
// System.out.println(con);
// }
// Constructor<?> constructor = aClass.getConstructor();
// System.out.println(constructor);
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class);
System.out.println(declaredConstructor);
declaredConstructor.setAccessible(true);
Student david = (Student)declaredConstructor.newInstance(18);
System.out.println(david.getAge());
}
}
运行结果
2.3利用反射获取成员变量
获取到成员变量,对成员变量进行赋值和取值操作。
示例代码
Student类
java
package com.wangwei.myreflect3;
public class Student {
public Student(){
}
public Student(String name){
this.name=name;
}
private Student(int age){
this.age=age;
}
protected Student(String name, int age){
this.name=name;
this.age=age;
}
public Student(String name, int age,String gender){
this.name=name;
this.age=age;
this.gender=gender;
}
private String name;
private int age;
public String gender;
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 getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
Demo3类
java
package com.wangwei.myreflect3;
import java.lang.reflect.Field;
/**
* 通过反射获取成员变量
*/
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//1.获取class字节码文件的对象
Class<?> aClass = Class.forName("com.wangwei.myreflect3.Student");
//2.获取公共成员变量
// Field[] fields = aClass.getFields();
// for(Field field:fields){
// System.out.println(field);
// }
//获取所有成员变量
// Field[] declaredFields = aClass.getDeclaredFields();
// for(Field field:declaredFields){
// System.out.println(field);
// }
//获取单个公共的成员变量
Field gender = aClass.getField("gender");
System.out.println(gender);
//获取成员变量的值
Student student = new Student("David", 18, "男");
String value = (String)gender.get(student);
System.out.println(value);
//修改对象成员变量的值
gender.set(student,"Daxi");
String value1 = (String)gender.get(student);
System.out.println(value1);
}
}
运行结果
2.4利用反射获取成员方法
Student类
java
package com.wangwei.myreflect4;
public class Student {
public Student(){
}
public Student(String name,int age){
}
private String name;
private int 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;
}
public void sleep(){
System.out.println("睡觉");
}
private void eat(String something){
System.out.println("吃"+something);
}
}
Demo4类
java
package com.wangwei.myreflect4;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo4 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//1.获取class字节码文件对象
Class<?> aClass = Class.forName("com.wangwei.myreflect4.Student");
//2.获取所有公共的方法对象(包含父类中的方法)
// Method[] methods = aClass.getMethods();
// for (Method method:methods){
// System.out.println(method);
// }
//获取所有的方法对象(不能回去父类的,但是可以获取本类中私有的方法
// Method[] declaredMethods = aClass.getDeclaredMethods();
// for (Method method:declaredMethods){
// System.out.println(method);
// }
//获取具体方法对象
Method eat = aClass.getDeclaredMethod("eat", String.class);
System.out.println(eat);
//方法运行
Student student = new Student();
eat.setAccessible(true);
eat.invoke(student, "汉堡");
}
}
运行结果
三、总结
- 在项目新架构中大量使用了反射,越发能够体会到反射的强大之处,是实现架构底层高复用、高扩展、高维护的实现方式之一。
四、升华
- 学习是一个迭代的过程:通过这一次的博客总结,博主对于反射的概念理解以及在宏观的运用上达到了熟练的层次。