Java中反射的作用与原理

1.定义:

反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意个对象,都能够调用它的任意一个方法。在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

解释:反射就像是一个程序员的万能钥匙,可以让程序员在程序运行时,动态地获取一个类的信息,创建对象,调用方法等操作。反射的核心就是Java中的Class类,它包含了类的信息(包括类名、属性、方法等),可以让程序员在程序运行时,动态地获取这个Class对象,并通过这个Class对象来访问类的信息和操作类的对象。


2.反射的实现方式:

第一步:

获取Class对象,有4种方法:
1)Class.forName(“类的路径”);

该方法可以根据类的全限定名(包名+类名)来获取对应的Class对象,从而实现动态加载类。

例如,我们可以通过以下代码获取String类的Class对象:

Class<?> stringClass = Class.forName("java.lang.String");

2)类名.class

通过类名.class方式可以获取类的Class对象,这种方式比较简单,但是需要明确类的类型。

例如,我们可以通过以下代码获取String类的Class对象:

Class<String> stringClass = String.class;

3)对象名.getClass()

通过实例对象的getClass()方法可以获取其对应的Class对象,从而实现动态获取对象的类型信息。

例如,我们可以通过以下代码获取一个字符串对象的Class对象:

String str = "Hello, world!";
Class<? extends String> strClass = str.getClass();

第二步:

再获取到Class对象之后,就可以通过Class对象来获取类的信息、创建对象、调用方法等操作了。

1)获取类的信息

可以通过Class对象来获取类的各种信息,例如类的名称、包名、父类、接口、字段、方法等等。下面是一些示例代码:

Class<?> personClass = Class.forName("com.example.Person");

// 获取类的名称
String className = personClass.getName();

// 获取类的包名
Package classPackage = personClass.getPackage();
String packageName = classPackage.getName();

// 获取类的父类
Class<?> superClass = personClass.getSuperclass();

// 获取类实现的接口
Class<?>[] interfaces = personClass.getInterfaces();

// 获取类的字段
Field[] fields = personClass.getDeclaredFields();

// 获取类的方法
Method[] methods = personClass.getDeclaredMethods();

2)创建对象

通过Class对象来创建对象,包括使用无参构造函数创建对象、使用有参构造函数创建对象、使用静态工厂方法创建对象等等。下面是一些示例代码:

Class<?> personClass = Class.forName("com.example.Person");

// 使用无参构造函数创建对象
Object person = personClass.newInstance();

// 使用有参构造函数创建对象
Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
Object person = constructor.newInstance("Tom", 20);

// 使用静态工厂方法创建对象
Method factoryMethod = personClass.getMethod("createPerson");
Object person = factoryMethod.invoke(null);

3)调用方法

通过Class对象来调用类的方法,包括调用普通方法、调用静态方法、调用私有方法等等。下面是一些示例代码。

Class<?> personClass = Class.forName("com.example.Person");
Object person = personClass.newInstance();

// 调用普通方法
Method sayHelloMethod = personClass.getMethod("sayHello");
sayHelloMethod.invoke(person);

// 调用静态方法
Method staticMethod = personClass.getMethod("staticMethod");
staticMethod.invoke(null);

// 调用私有方法
Method privateMethod = personClass.getDeclaredMethod("privateMethod");
privateMethod.setAccessible(true);
privateMethod.invoke(person);

3.Java中实现反射机制的类:

1)Class:是Java反射机制的核心类,它代表一个类的类型信息,可以用来获取类的各种信息,包括类的名称、包名、父类、接口、字段、方法等等。

注意: 所有获取对象的信息都需要Class类来实现。
2)Field:提供有关类和接口的属性信息,以及对它的动态访问权限。

它代表一个类的属性,可以用来访问属性。通过Field类可以获取一个类的所有属性,包括公有属性和私有属性。
3)Constructor:Constructor类代表一个类的构造函数,可以用来创建对象。通过Constructor类可以获取一个类的所有构造函数,包括无参构造函数和有参构造函数。
4)Method:代表一个类的方法,可以用来调用方法。通过Method类可以获取一个类的所有方法,包括普通方法、静态方法、私有方法等等。


4.反射机制的优缺点:


优点
1)能够运行时动态获取类的实例,提高灵活性;
2)与动态编译结合,它是通用的机制,也可以用于各种框架和工具
缺点:
1)使用反射性能较低,需要解析字节码,将内存中的对象进行解析。
解决方案:可以通过setAccessible(true)关闭JDK的安全检查来提升反射速度;
多次创建一个类的实例时,有缓存会快很多;
ReflectASM工具类,通过字节码生成的方式加快反射速度;
2)相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值