一、什么是反射
计算机科学术语
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。(程序集包含模块,而模块包含类型,类型又包含成员。)
用途
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。
6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
优点
1、反射提高了程序的灵活性和扩展性。
2、降低耦合性,提高自适应能力。
3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
缺点
1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
本人理解:
反射它是框架设计的灵魂。
框架: 它就是一个半成品,客户可以引入该框架,在框架的基础上填写自己的业务代码。提高开发效率。 比如: springmvc mybatis框架 。
反射: 它就是把类中成员封装到其他类对象的形式。在通过该类对象可以获取成员的信息。
二、获取Class反射类的方式
获取反射类有三种方式
第一种方式 Class.forName(“类的全路径”)
package demo2;
public class Text {
public static void main(String[] args) throws ClassNotFoundException {
//第一种获取反射类方式
Class<?> aClass = Class.forName("demo2.Student");
}
}
<bean id="s" class="com.aaa.Student">
app.getBean("s");
第二种方式 类.Class
package demo2;
public class Text {
public static void main(String[] args) throws ClassNotFoundException {
//第一种获取反射类方式
//Class<?> aClass = Class.forName("demo2.Student");
//第二种获取反射类方式
Class<Student> aClass1 = Student.class;
}
}
Mybatis----session.getMapper(StudentDao.class)
第三种方式 对象名.getClass()
package demo2;
public class Text {
public static void main(String[] args) throws ClassNotFoundException {
//第一种获取反射类方式
//Class<?> aClass = Class.forName("demo2.Student");
//第二种获取反射类方式
//Class<Student> aClass1 = Student.class;
//第三种获取反射类方式
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
}
}
三种获取反射类的方式引用地址值相等吗?
package demo2;
public class Text {
public static void main(String[] args) throws ClassNotFoundException {
//第一种获取反射类方式
Class<?> aClass = Class.forName("demo2.Student");
//第二种获取反射类方式
Class<Student> aClass1 = Student.class;
//第三种获取反射类方式
Student student = new Student();
Class<? extends Student> aClass2 = student.getClass();
//三种获取反射类方式的引用地址值相等
System.out.println(aClass==aClass1);
System.out.println(aClass1==aClass2);
System.out.println(aClass2==aClass);
}
}
三、通过反射类获取对应的类对象
获取方式:
反射对象.newinstance()
package demo2;
public class Text1 {
public static void main(String[] args) throws Exception {
//获取反射类
Class<Student> aClass = Student.class;
//通过反射类获取反射对象
Student student = aClass.newInstance();
//通过反射类再次获取反射对象
Student student2 = aClass.newInstance();
//输出反射对象
System.out.println(student);
System.out.println(student2);
//比较反射对象 比较的是引用地址值 地址值不能
System.out.println(student==student2);
}
}
四、获取属性类对象
getDeclaredField (通过反射类获取本类中单一属性对象)
getDeclaredFields (通过反射类获取本类中所有属性对象)
getField (通过反射类获取本类以及父类中由public修饰的单一属性)
getFields (通过反射类获取本类以及父类中所有public修饰的属性)
package demo2;
import java.lang.reflect.Field;
public class Text2 {
public static void main(String[] args) throws Exception {
//获取反射类对象
Class<Student> aClass = Student.class;
//通过反射类对象获取name属性
Field name = aClass.getDeclaredField("name");
System.out.println(name);
//通过反射类获取本类中所有属性
Field[] fields = aClass.getDeclaredFields();
for (Field f : fields) {
System.out.println(f);
}
//通过反射类获取name属性
Field name1 = aClass.getField("name");
System.out.println(name1);
//通过反射类获取本类以及父类中所有 public 修饰的属性
Field[] fields1 = aClass.getFields();
System.out.println(fields1);
}
}
Class<Student> aClass = Student.class;
// Field sexField = aClass.getDeclaredField("sex");
// System.out.println(sexField);
// Field phone = aClass.getDeclaredField("phone");
// System.out.println(phone);
Field[] declaredFields = aClass.getDeclaredFields();
for (Field f:declaredFields){
System.out.println(f);
}
System.out.println("获取本类以及父类中所有public属性对象");
// Field address = aClass.getField("address");
// System.out.println(address);
// Field phone = aClass.getField("phone");
// System.out.println(phone);
Field[] fields = aClass.getFields();
for (Field field:fields) {
System.out.println(field);
}
Field类中常见的方法
setAccessible(true) 设置私有访问权限
set(obj,value)(对象名,属性值)
package demo2;
import java.lang.reflect.Field;
public class Text3 {
public static void main(String[] args) throws Exception {
//获取反射类
Class<Student> aClass = Student.class;
//通过反射类获取类对象
Student student = aClass.newInstance();
System.out.println(student);
//通过反射类获取name属性 getDeclaredField 获取本类中所有属性包括私有属性
Field name = aClass.getDeclaredField("name");
//打开私有访问权限
name.setAccessible(true);
//为对象student的name属性赋值阿娇
name.set(student,"阿娇");
System.out.println(student);
}
}
Class<Son> sonClass = Son.class;
Son son = sonClass.newInstance();
System.out.println(son);
Field nameField = sonClass.getDeclaredField("name");
//IllegalAccessException:
nameField.setAccessible(true); //设置私有访问权限
nameField.set(son,"刘德华"); //为对象son的name属性赋值“刘德华”
System.out.println(son);
五、获取方法类对象
getDeclaredMethod(通过反射类获取本类中单一方法属性 需要传入方法名以及参数)
getDeclaredMethods (通过反射类获取本类中所有方法属性 包括私有属性)
getMethod (通过反射类获取本类以及父类中public修饰的方法属性 需要传入方法名以及参数)
getMethods (通过反射类获取本类以及父类中所有public修饰的方法属性)
package demo2;
import java.lang.reflect.Method;
public class Text4 {
public static void main(String[] args) throws Exception {
//获取反射类
Class<Student> aClass = Student.class;
//获取反射类对象
Student student = aClass.newInstance();
//通过反射类获取本类中单一方法属性
Method show = aClass.getDeclaredMethod("show", Integer.class);
//通过反射类获取本类中所有方法属性 包括私有属性
Method[] methods = aClass.getDeclaredMethods();
//通过反射类获取本类以及父类中public修饰的方法属性
Method show1 = aClass.getMethod("show", Integer.class);
//通过反射类获取本类以及父类中所有public修饰的方法属性
Method[] methods1 = aClass.getMethods();
}
}
Method类中常见方法
invoke(执行方法)
语法:方法名.invoke(对象名,参数)
package demo2;
import java.lang.reflect.Method;
public class Text4 {
public static void main(String[] args) throws Exception {
//获取反射类
Class<Student> aClass = Student.class;
//获取反射类对象
Student student = aClass.newInstance();
//通过反射类获取本类中单一方法属性
Method show = aClass.getDeclaredMethod("show", Integer.class);
//通过反射类获取本类中所有方法属性 包括私有属性
Method[] methods = aClass.getDeclaredMethods();
//通过反射类获取本类以及父类中public修饰的方法属性
Method show1 = aClass.getMethod("show", Integer.class);
//通过反射类获取本类以及父类中所有public修饰的方法属性
Method[] methods1 = aClass.getMethods();
//执行获取到的方法 invoke执行该方法 ()传入对象以及方法的参数
Object invoke = show.invoke(student, 18);
}
}
六、获取Constructor对象
getConstructor(通过反射类获取本类中的构造方法)
package demo2;
import java.lang.reflect.Constructor;
public class Text5 {
public static void main(String[] args) throws Exception {
//获取反射类
Class<Student> aClass = Student.class;
//通过反射类获取无参构造
Constructor<Student> constructor = aClass.getConstructor();
//通过无参构造创建对象
Student student = constructor.newInstance();
//通过反射类获取有参构造
Constructor<Student> constructor1 = aClass.getConstructor(String.class);
//通过有参构造创建对象
Student student1 = constructor1.newInstance("阿娇");
}
}
package demo2;
public class Student extends Fun {
private String name;
public int age;
String sex;
public void show(Integer id){
}
public Student(String name) {
this.name = name;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
package com.demo03;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* @program: test
* @description:
* @author: 闫克起2
* @create: 2023-06-07 11:04
**/
public class Test03 {
public static void main(String[] args) throws Exception {
Class<?> aClass = Class.forName("com.demo03.Son");
Constructor<?> constructor = aClass.getConstructor();
Object o = constructor.newInstance(); //<bean />
System.out.println(o);
Constructor<?> constructor1 = aClass.getConstructor(Object.class, int.class);
Object instance = constructor1.newInstance("刘德华", 28);
System.out.println(instance);
}
}
class Son{
private String name;//private=2 public=1 default=0 protected=4
public int age;
public void show(Integer a,String n){
System.out.println("~~~~~~~~~~~~~~~~~~show~~~~~~~~~~~~~"+a+";;name="+n);
}
public Son(String name) {
this.name = name;
}
public Son() {
}
public Son(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Son{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}