Java基础反射

反射

1.反射原理

Java 中反射机制是在程序运行时,对本身所构成的程序进行访问和修改的能力。它主要设计以下三个类:Class、Method、Constructor。通过反射,我们可以在程序运行时动态地获取和操作类的信息,包括类名、字段、方法、构造函数等。

Java 中所有类都是一个模板,因此整个类对于 Java 而言是一个【类的类型】 Class类型
class 类名 {
    成员变量; // Field
    成员方法; // Method
    构造方法; // Constructor
}
成员变量 Field 模板【成员变量类】
对于一个成员变量而言,变量名是唯一的,同时需要关注当前成员变量所在哪一个类
修饰符 数据类型 成员变量名称;
成员方法 Method 模板【成员方法类】
对一个成员方法而言,在调用方法的过程中,我们所关注的是方法名和形式参数列表数据类型,同时需要关注,当前成员方法所在哪一个类。
修饰符 返回值类型 方法名(形式参数列表);
构造方法 Constructor 模块【构造方法类】
对于一个构造方法而言,在调用过程中唯一的区别是形式参数列表,同时需要关注,当前构造方法所在哪一个类
修饰符 类型(形式参数列表);
2. Class 类型

Class 类是 Java 反射机制的入口点,它代表一个类的字节码文件,可以获取类中的各种信息,如属性、方法、构造器等,也可以创建一个类的对象。Class 类型对象是 Java 类型在内存方法区空间内容

class ClassName {
    Field[] fields; // 成员变量 Field 类型数组,成员变量有多个,有一个,或者没有
    Constructor[] constructors; // 构造方法 Constructor ;类型数组,构造方法至少有一个,可能允许多个
    Method[] methods; // 成员方法 Method 类型数组,成员方法可以是一个,多个或者没有。
}
2.1 Class 类型对象获取方法
获取 Class 对象的常用方式有:
对象.getClass() 方法
类.class
Class.forName() 方法
2.1.1 Class.getClass()
Class<? extends T> 任意类对象.getClass(); Java 中任意一个类对象,都可以通过 getClass 方法获取对对应的 Class 类型对象。该方法是 Object 类提供给 Java 中所有类型使用的方法
Person person = new Person(); Class<? extends Person> cls = person.getClass();
2.1.2 类名.class
Class<T> 类名.class; 通过 Java 中任意的类名,获取其属性内容,得到对应的 Class 对象。
Class<Person> cls = Person.class;
2.1.3 Class.forName()
Class<?> Class.forName(String packageAndClassName); Class 类提供的静态成员方法,根据用户提供的完整的包名.类名,获取对应数据类型的 Class 对象。
Class<?> cls = Class.forName("Person");
3. Constructor 构造方法类型
Constructor 类代表一个类的构造方法,在使用反射创建一个类的对象时会用到。对于 Class 对象,构造方法的名称是【类名】,不具备唯一性,在实际调用构造方法时,区分构造方法的不同是通过 (参数列表,参数数据类型,参数个数,参数顺序)来区分,即最重要的是形式参数列表。
3.1 通过 Class 对象获取对应的 Constructor 构造方法对象
Constructor[] getConstructors();
// 获取当前 Class 对应数据类型的所有【非私有化】构造方法对象数组
Constructor[] getDeclaredConstructors();
// 获取当前 Class 对应数据类型的所有构造方法对象数组,包括【私有化构造方法】
Constructor getConstructor(Class... parameterTypes);
// 根据用户指定的参数类型,顺序,个数获取对应的 Constructor 构造方法对象,并且是【非私有化】构造方法
public Student(){...}
public Student(int id) {...}
public Student(int id, String name) {...}
public static void mian(String[] args) {
    Class <?> cls = Class.forName("Student");
    
    Constructor c1 = cls.getConstructors();
    Constructor c2 = cls.getConstructors(int.class);
    // 约束当前构造方法的参数类型是 (int)
    Constructor c3 = cls.getConstructors(int.class,String.class);
    // 约束当前构造方法的参数类型是 (int, String)
}
Constructor getDeclaredConstructor(Class... parameterTypes);
// 根据用户指定的参数类型,顺序,个数获取对应的 Constructor 构造方法对象,可以获取私有化构造方法
public Student(String name) {...}
public static void mian(String[] args) {
    Class <?> cls = Class.forName("Student");
    Constructor declareConstructor = cls.getDeclaredConstructor(String.class);
}
4. Method
Method 类代表一个类的方法,在使用反射执行一个类的方法时会用到。Method 成员方法类型通过 Class 对象获取关注点是方法名和形式参数列表。
4.1 通过 Class 对象获取对应的 Method 成员方法对象
Method[] getMethods();
// 可以获取 Class 对象对应类型的所有非私有化成员方法数组,包括父类继承给子类可以提供给子类使用的成员方法
Method[] getDeclaredMethods();
// 可以获取 Class 对象对应类型的所有成员方法对象数组,包括私有化成员方法,但是不包括继承方法父类的成员方法。有且只有子类自身方法
Method getMethod(String methodName, Class... parameterTypes);
// 根据指定的方法名称 (methodName) 和指定的方法参数类型,获取成员方法对象,只能是非私有化成员方法和父类继承给子类使用的方法。 
public void student() {...}
public void student(String name) {...}
public static void mian(String[] args) {
    Class <?> cls = Class.forName("Student");
    
    Method m1 = cls.getMethod("student");
    
    Method m2 = cls.getMethod("student", String.class);
}
Method getDeclaredMethod(String methodName, Class... parameterTypes);
// 根据指定的方法名称 (methodName) 和指定的方法参数类型,获取成员方法对象,包括私有化成员方法,不包括父类继承到子类的方法。仅获取子类自有方法
private void grow(int minCapacity) {...}
private void rangCheck(int index) {...}
private void test(int num, float num2, double num3);

public static void mian(String[] args) {
 Class<?> cls = Class.forName("ArrayList");
    
     Method m1 = cls.getDeclaredMethod("grow", int.class);
     Method m2 = cls.getDeclaredMethod("rangCheck", int.class);
    Method m3 = cls.getDeclaredMethod("test", int.class, float.class, double.class);
}
5.反射应用场景
动态代理:
动态代理是 Java 反射机制实际应用的重要场景之一,在动态代理中,程序可以代表另一个对象来执行某个操作,而不用暴露原有对象的引用。这一机制在框架中有着广泛的应用。
6. 优点和缺点
优点:
1. 动态性: 反射机制允许程序在运行时动态地访问和修改对象、方法和属性等信息,这种动态性能够帮助我们在程序运行时适应变化。
2. 灵活性: 反射机制让我们可以动态地创建和使用对象,而不需要在程序编译时就确定类的存在。
缺点:
1. 性能问题: 反射机制的调用效率相对于直接调用要慢得多,因为它需要在运行时动态地定位对象的属性和方法。
2. 安全问题: 反射机制可以访问和修改私有属性和方法,这可能会导致安全漏洞。因此,需要谨慎使用反射机制,以避免安全问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值