学习aspmvc网站开发 书,东莞营销商城网站建设,做暖暖欧美网站,爱链网中可以进行链接买卖提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、反射是什么#xff1f;二、反射有啥好处#xff1f;1. 没反射2. 有反射 三、反射的常用方法1. 获取 Class 对象#xff1a;2. 获取类的构造方法#xf… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、反射是什么二、反射有啥好处1. 没反射2. 有反射 三、反射的常用方法1. 获取 Class 对象2. 获取类的构造方法3. 获取类的字段信息4. 获取类的方法信息5. 创建对象和调用方法 四、总结 前言
提示小车车准备出发。。。。。
今天咋们来搂一搂反射是啥有啥用各位请上车系好安全带。。。。 提示路途颠簸系好安全带
一、反射是什么
当我们写Java程序时通常情况下我们会在编译时确定所有的类、方法和属性。但是有些时候我们希望在程序运行时动态地获取和操作类的信息这就是反射。
反射是指在运行时动态地获取类的信息并操作类的成员。
在Java中每个类都有一个对应的Class对象这个对象包含了类的信息如类的名称、属性、方法等。反射机制允许我们在运行时获取这个Class对象进而获取和操作类的信息。
⚠️这里给大家提个小问题为什么Java只能在程序运行阶段才能动态获取类的信息并操作类的成员呢
原因如下
类加载 在 Java 程序运行时JVM 负责加载类的字节码文件。这个过程称为类加载。类加载器将字节码加载到内存中并创建对应的 Class 对象该对象包含了类的信息。实例化对象 通过 Class 对象可以实例化类的对象。反射允许在运行时创建类的对象而不需要在编译时知道类的确切类型。动态获取信息 通过 Class 对象可以获取类的各种信息包括类的名称、构造方法、字段、方法等。这使得程序在运行时能够根据需要动态地获取和操作类的信息。
总而言之当一个类.class文件被classloader加载到内存后它会将.class文件里面的内容加载到Metaspace中并且会生成一个类对象。这个类对象存储在Metaspace中它充当了访问类的结构和内容的入口包括静态字段、方法等。 有兴趣的同学可以去学学JVM的相关知识。
二、反射有啥好处
对于干干净净的小白同学先绕道去第三部分了解一下反射的常用方法再来品味好吃的会更有感觉哦。 反射的好处咱们就举个有反射和没反射的例子对比说明一下子。 首先定义一个支付接口 Mtwm
// Mtwm.java
public interface Mtwm {void payOnline();
}然后实现两个支付方式类分别是 WeChat 和 AliPay
// WeChat.java
public class WeChat implements Mtwm {Overridepublic void payOnline() {System.out.println(我已经点了外卖正在使用微信支付);}
}public class AliPay implements Mtwm {Overridepublic void payOnline() {System.out.println(我已经点了外卖正在使用支付宝支付);}
}1. 没反射
接下来创建一个测试类 Test用于模拟前台选择支付方式
// Test.java
public class Test {public static void main(String[] args) {String str 微信; // 模拟前台支付方式选择if (微信.equals(str)) {pay(new WeChat());}if (支付宝.equals(str)) {pay(new AliPay());}}public static void pay(Mtwm paymentMethod) {paymentMethod.payOnline();}
}以上是使用多态的方式已经不错了哦。但在实际应用中若是我又增加了一个 “银行卡支付” 诸君又该如何应对 我举手我回答。 无非就两步嘛
1、创建一个新类implement Mtwm重写payOnline方法 2、在多加一个if的判断分支。
但是当我们引入反射机制会发生什么神奇的事情呢
2. 有反射
// Demo.java
import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws Exception {// 模拟前台支付方式选择String str com.zhaoss.test01.AliPay; // 实际上是支付类的全限定路径// 利用反射Class? cls Class.forName(str);Object instance cls.newInstance();// 获取 payOnline 方法并调用Method method cls.getMethod(payOnline);method.invoke(instance);}
}各位有没有发现通过使用反射可以在不修改测试类的情况下引入新的支付方式。这样我们就只要创建一个新类implement Mtwm重写payOnline方法然后提供新支付方式的实现类并传入其全路径名而无需修改测试类。是不是很哇塞
三、反射的常用方法
哥哥们原谅我懒。我把输出写到注释里了不好看的话可以直接搞到本地跑一下子。
1. 获取 Class 对象
通过对象的 getClass() 方法或者类名的 .class 字面量可以获取类的 Class 对象。
public class Example {public static void main(String[] args) {// 通过对象的getClass()方法获取Class对象String str Hello, Reflect!;Class? classObj1 str.getClass();System.out.println(classObj1.getName()); // 输出java.lang.String// 通过类名的.class字面量获取Class对象Class? classObj2 String.class;System.out.println(classObj2.getName()); // 输出java.lang.String}
}2. 获取类的构造方法
通过 getConstructors() 方法获取类的所有公共构造方法通过 getDeclaredConstructors() 获取所有构造方法包括私有的。
import java.lang.reflect.Constructor;public class Example {public Example(String message) {System.out.println(Constructor with message: message);}public static void main(String[] args) throws Exception {Class? clazz Example.class;// 获取所有公共构造方法Constructor?[] constructors clazz.getConstructors();for (Constructor? constructor : constructors) {System.out.println(Public Constructor: constructor);//输出Public Constructor: public SystemStudy.Example(java.lang.String)}// 获取所有构造方法包括私有的Constructor?[] allConstructors clazz.getDeclaredConstructors();for (Constructor? constructor : allConstructors) {System.out.println(All Constructor: constructor);//输出//All Constructor: public SystemStudy.Example(java.lang.String)//All Constructor: private SystemStudy.Example(java.lang.String,java.lang.Integer)}}
}3. 获取类的字段信息
通过 getFields() 方法获取类的所有公共字段通过 getDeclaredFields() 获取所有字段包括私有的。
import java.lang.reflect.Field;public class Example {public int publicField;private String privateField;public static void main(String[] args) {Class? clazz Example.class;// 获取所有公共字段Field[] fields clazz.getFields();for (Field field : fields) {//输出Public Field: public int SystemStudy.Example.publicFieldSystem.out.println(Public Field: field);}// 获取所有字段包括私有的Field[] allFields clazz.getDeclaredFields();for (Field field : allFields) {//输出//All Field: public int SystemStudy.Example.publicField//All Field: private java.lang.String SystemStudy.Example.privateFieldSystem.out.println(All Field: field);}}
}4. 获取类的方法信息
通过 getMethods() 方法获取类的所有公共方法通过 getDeclaredMethods() 获取所有方法包括私有的。 这里还有好多的Object包含的方法wait、equals、hashCode等太多了我就写了两个关键的。
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class Example {public void publicMethod() {System.out.println(Public Method);}private void privateMethod() {System.out.println(Private Method);}public static void main(String[] args) {Class? clazz Example.class;// 获取所有公共方法Method[] methods clazz.getMethods();for (Method method : methods) {//输出Public Method: public void SystemStudy.Example.publicMethod()System.out.println(Public Method: method);}// 获取所有方法包括私有的Method[] allMethods clazz.getDeclaredMethods();for (Method method : allMethods) {//输出//All Method: public void SystemStudy.Example.publicMethod()//All Method: private void SystemStudy.Example.privateMethod()System.out.println(All Method: method);}}
}5. 创建对象和调用方法
通过 newInstance() 方法创建类的实例并通过 invoke() 方法调用类的方法。
import java.lang.reflect.Method;public class Example {public void sayHello(String name) {System.out.println(Hello, name !);}public static void main(String[] args) throws Exception {Class? clazz Example.class;// 创建类的实例Object obj clazz.newInstance();// 获取方法并调用Method method clazz.getMethod(sayHello, String.class);method.invoke(obj, Reflect); // 输出Hello, Reflect!}
}这些是反射中常用的方法通过这些方法可以在运行时获取并操作类的信息使得代码更加灵活和动态。还有很多方法啊我就不挨个列举了。
四、总结
好啦以上就是本次对于反射的讲解。安全到站下车对于我的驾驶技术苟同的兄弟姐妹们点点赞。祝各位身体健康、吃嘛嘛香