Java反射机制【看这一篇就够啦!!!】

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于反射机制的相关操作吧

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一.是什么

二.为什么要使用

三.怎么使用

💡辉辉小贴士:什么是Class类呢?

1.反射实例化 

2.反射动态方法调用

3.反射读写属性

💡辉辉小贴士:反射有这么多优点,那么我们什么时候可以使用反射呢?


一.是什么

反射机制是Java语言中的一种高级特性,它可以在程序运行时动态获取类的信息、实例化对象、调用方法、访问和修改属性等。与之相对的是静态编译时期的程序设计方式,也是Java最初的设计方式

二.为什么要使用

反射机制在Java中十分重要,因为它提供了很多优秀的功能和特性

  • 1. 动态地获取和使用类的信息
    • 反射机制可以在程序运行时动态地获取类的信息,例如类的名称、字段、方法、注解等信息,从而进行一些动态操作,例如在JUnit中实现自动化测试时,通过反射获取类的所有测试方法,然后自动进行测试。
  • 2. 动态地创建和使用类的实例对象
    • 通过反射机制,我们可以动态地在程序运行时创建类的实例对象,这种方式使得代码更加灵活,可以根据业务需求动态地创建对象。例如在Spring框架中,就通过反射机制实现了依赖注入,并动态创建Bean实例。
  • 3. 动态地调用和修改类的方法和字段
    • 反射机制也可以处理类的方法和字段,通过反射机制,我们可以动态地调用和修改类的方法和字段,这种方式使得代码更加灵活和扩展性更强。例如在使用AOP技术时,就可以通过反射机制动态地调用目标方法,并实现一些统一的处理。
  • 4. 实现更加灵活的框架和工具
    • 反射机制可以为框架和工具提供更加灵活、可扩展和易用的接口,从而实现更加高效和智能的应用程序。例如在ORM框架中,通过反射机制可以将数据库中的表映射成Java类,从而实现快速地对表进行操作。

总而言之,反射机制可以为Java应用程序提供更加灵活、高效和智能的开发方式,通过反射机制,我们可以在程序运行时动态地调用和使用类的信息、方法和字段,从而实现更加高效和智能的应用程序

三.怎么使用

在学习怎么使用反射机制之前,我们需要知道Java反射机制的核心是Class类

💡辉辉小贴士:什么是Class类呢?

  • 在Java的反射机制中,"类类"通常指Class类。Class类是Java中用来表示一个类的类
  • 在Java程序运行时,每个类都会对于一个Class对象,Class对象包含了该类的各种元信息,例如类的名称、字段、方法等
  • 借助Class对象,Java程序可以在运行时动态地创建类的实例、调用类的方法等操作,这就是反射机制的基本功能之一
  • Class类中定义了很多方法,包括获取类的基本信息、实例化对象、获取字段和方法、修改字段和调用方法等,是Java反射机制的重要组成部分

上述描述还是太过于抽象,下面我们将通过代码更清晰的了解到什么是类类

package com.wh.reflect;public class Demo1 {/*** 什么是类类*/// ①🐱猫类🐱里面会有很多的小猫,例如咪咪,加菲猫...// ②🐕狗类🐕里面也会有很多小狗,例如旺财,来福...// ③人类里面也会有很多小人,例如夏威大傻逼,王辉大美女// 咪咪,加菲猫是猫类的实例// 旺财,来福是狗类的实例// 夏威大傻逼,王辉大美女是人类的实例// 那么人类,狗类,猫类又是谁的实例呢?// 在这里我们就可以引入Class类的概念了:Class类是Java中用来表示一个类的类// 所以人类,狗类,猫类都是Class类的实例!!!!/*** 1.2为什么要学习类类* @throws Exception */// 因为Class类是Java反射机制的基础之一public static void main(String[] args) throws Exception {/*** 1.3怎么获取类类*/Student stu = new Student();//1.对象.getclassClass c1 = stu.getClass();System.out.println(c1);//2.类名.classClass c2 = Student.class;System.out.println(c2);// class com.wh.reflect.Student//3.Class.forName("全路径名");Class c3=Class.forName("com.wh.reflect.Student");System.out.println(c3);}}

相信通过以上代码,我们已经能够了解到什么是类类了,那么接下来我们就看看反射机制到底怎么使用吧!!

对于反射机制的使用操作,全部以Student类作为实例👇👇

package com.wh.reflect;public class Student {private String sid;private String sname;public Integer age;static{System.out.println("加载进jvm中!");}public Student() {super();System.out.println("调用无参构造方法创建了一个学生对象");}public Student(String sid) {super();this.sid = sid;System.out.println("调用带一个参数的构造方法创建了一个学生对象");}public Student(String sid, String sname) {super();this.sid = sid;this.sname = sname;System.out.println("调用带二个参数的构造方法创建了一个学生对象");}@SuppressWarnings("unused")private Student(Integer age) {System.out.println("调用Student类私有的构造方法创建一个学生对象");this.age = age;}public String getSid() {return sid;}public void setSid(String sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public void hello() {System.out.println("你好!我是" + this.sname);}public void hello(String name) {System.out.println(name + "你好!我是" + this.sname);}@SuppressWarnings("unused")private Integer add(Integer a, Integer b) {return new Integer(a.intValue() + b.intValue());}
}

1.反射实例化 

反射实例化的方法
newInstance()来创建指定类的实例对象
getConstructor(Class)调用公共的有参构造器,括号中的参数是构造器中的参数类型的类类
getDeclaredConstructor(Class)调用私有的有参构造器,括号中的参数是构造器中的参数类型的类类
setAccessible(Boolean)该方法用于设置方法、字段或者构造方法在访问时,是否需要在访问时取消Java语言访问修饰符的限制。也就是说,如果设置为 true,那么反射对象在使用时就不再需要考虑它的访问修饰符的限制。简而言之就是,可以调用到私有的方法、字段或者构造方法
package com.wh.reflect;import java.lang.reflect.Constructor;/*** 什么是反射?* 反射机制是Java语言中的一种高级特性,* 它可以在程序运行时动态获取类的信息、实例化对象、调用方法、访问和修改属性等。* 与之相对的是静态编译时期的程序设计方式,也是Java最初的设计方式* * 反射实例化 * * @author W**/
public class Demo2 {
public static void main(String[] args) throws Exception {//一切反射从类类开始Class cla =Class.forName("com.wh.reflect.Student");//1.调用无参构造器【如果写了有参构造器,那么一定要记得补一个无参构造器】Student stu1 = (Student) cla.newInstance();//调用无参构造方法创建了一个学生对象System.out.println(stu1);//com.wh.reflect.Student@7852e922//2.调用有一个参构造器Constructor constructor1=cla.getConstructor(String.class);Student stu2 = (Student)constructor1.newInstance("wh1");//调用带一个参数的构造方法创建了一个学生对象System.out.println(stu2);//com.wh.reflect.Student@4e25154f//3.调用带两个/多个参数的构造器Constructor constructor2=cla.getConstructor(String.class,String.class);Student stu3 = (Student)constructor2.newInstance("wh1","王辉");//调用带二个参数的构造方法创建了一个学生对象System.out.println(stu3);//com.wh.reflect.Student@70dea4e//4.调用私有的有一个参构造器的方法Constructor constructor3=cla.getDeclaredConstructor(Integer.class);constructor3.setAccessible(true);Student stu4 = (Student) constructor3.newInstance(11);//调用Student类私有的构造方法创建一个学生对象System.out.println(stu4);//	com.wh.reflect.Student@5c647e05}
}

注意1:在我们使用newInstance()方法,去调用特定对象的无参构造器时,我们一定要保证其里面有无参构造器【如果写了有参构造器,那我们需要补一个无参构造器】

如果没有写无参构造器的话,那么将会抛出一个异常

 注意2:在我们调用私有的方法、字段或者构造方法时,如果没有在调用之前使用setAccessible这个方法,则无法调用到私有的方法、字段或者构造方法,并且还会抛出一个异常

2.反射动态方法调用

反射动态方法调用中的方法
newInstance()来创建指定类的实例对象
getMethod(String, Class...)获取到特定对象中的共有的方法,第一个参数是方法的名字,第二个是一个可变参数,是该方法中的参数类型的类类
getDeclaredMethod(String, Class)获取到特定对象中的私有的方法,第一个参数是方法的名字,第二个是一个可变参数,是该方法中的参数类型的类类
 invoke(Object,Object... args) 根据传入的对象和参数,动态地在运行时调用指定对象的指定方法,返回的值是该方法的返回值,如果没有返回值,则该值为null
setAccessible(Boolean)该方法用于设置方法、字段或者构造方法在访问时,是否需要在访问时取消Java语言访问修饰符的限制。也就是说,如果设置为 true,那么反射对象在使用时就不再需要考虑它的访问修饰符的限制。简而言之就是,可以调用到私有的方法、字段或者构造方法
package com.wh.reflect;import java.lang.reflect.Method;/*** 什么是反射?* 反射机制是Java语言中的一种高级特性,* 它可以在程序运行时动态获取类的信息、实例化对象、调用方法、访问和修改属性等。* 与之相对的是静态编译时期的程序设计方式,也是Java最初的设计方式* * 反射动态方法调用* @author W**/
public class Demo3 {
public static void main(String[] args) throws Exception {// 一切反射从类类开始Class cla = Class.forName("com.wh.reflect.Student");Student stu = (Student) cla.newInstance();// 1.调用无参方法Method m1 = cla.getMethod("hello");System.out.println(m1);// public void com.wh.reflect.Student.hello()Object invoke1 = m1.invoke(stu);// 你好!我是nullSystem.out.println(invoke1);// null// 2.调用有参的方法Method m2 = cla.getMethod("hello", String.class);System.out.println(m2);// public void com.wh.reflect.Student.hello(java.lang.String)Object invoke2 = m2.invoke(stu, "傻逼");// 傻逼你好!我是nullSystem.out.println(invoke2);// null// 3.调用私有的有参方法Method m3 = cla.getDeclaredMethod("add", Integer.class, Integer.class);System.out.println(m3);// private java.lang.Integer// com.wh.reflect.Student.add(java.lang.Integer,java.lang.Integer)m3.setAccessible(true);Object invoke3 = m3.invoke(stu, 1, 1);System.out.println(invoke3);// 2}
}

3.反射读写属性

反射读写属性所用到的方法
getDeclaredField(String)拿到特定对象中特定的属性
getDeclaredFields()拿到特定对象中所有的属性
getName()拿到特定对象中所有的属性的属性名
get(Object)拿到特定对象中所有的属性的属性值,传入的参数为特定对象的对象名
set(Object ,Object)为指定对象修改指定的属性值
setAccessible(Boolean)该方法用于设置方法、字段或者构造方法在访问时,是否需要在访问时取消Java语言访问修饰符的限制。也就是说,如果设置为 true,那么反射对象在使用时就不再需要考虑它的访问修饰符的限制。简而言之就是,可以调用到私有的方法、字段或者构造方法
package com.wh.reflect;import java.lang.reflect.Field;/*** 什么是反射?* 反射机制是Java语言中的一种高级特性,* 它可以在程序运行时动态获取类的信息、实例化对象、调用方法、访问和修改属性等。* 与之相对的是静态编译时期的程序设计方式,也是Java最初的设计方式* * 反射读写属性* @author W**/
public class Demo4 {public static void main(String[] args) throws Exception {// 一切反射从类类开始Class cla = Class.forName("com.wh.reflect.Student");Student stu = new Student("wh2", "小王辉");stu.age=22;/*** 修改对象中的属性*/Field ageField = cla.getDeclaredField("age");ageField.setAccessible(true);ageField.set(stu, 18);/*** 老版本:拿到student类的所有属性【也就是拿到某一个特定对象的所有的属性】*///以前用的方式String sid = stu.getSid();System.out.println(sid);//wh2String sname = stu.getSname();System.out.println(sname);//小王辉/*** 新版本:拿到student类的所有属性【也就是拿到某一个特定对象的所有的属性】*/Field[] declaredFields = cla.getDeclaredFields();for (Field field : declaredFields) {field.setAccessible(true);System.out.println(field.getName()+":"+field.get(stu));//sid:wh2  sname:小王辉  	age:22}}
}

💡辉辉小贴士:反射有这么多优点,那么我们什么时候可以使用反射呢?

那就让我们来看看它的应用场景吧!!

  • 1. 依赖注入框架
    • 依赖注入(DI)框架可以通过反射机制来创建实例对象,并通过注解或XML配置来设置对象的属性和方法。例如Spring框架中的@Autowired注解就是通过反射机制来实现依赖注入。
  • 2. ORM框架
    • 对象关系映射(ORM)框架可以通过反射机制来将数据库中的表映射成Java类,并进行相关的增删改查操作。例如Hibernate框架就是使用反射机制来将数据库表映射为Java对象。
  • 3. 实现动态代理
    • 动态代理技术可以通过反射机制动态生成代理对象,并进行相关的操作。例如在AOP编程中,就可以通过动态代理技术实现统一的日志、事务等操作。
  • 4. 实现自动化测试
    • 通过反射机制,可以在运行时获取类的信息和方法信息,从而实现自动化测试的功能。例如JUnit框架就是通过反射机制来获取测试类和测试方法的信息,并进行测试操作。
  • 5. 实现插件化
    • 通过反射机制,可以实现插件化的功能。例如在Eclipse IDE中,就可以通过定义扩展点和插件来实现插件化的功能。

               好啦,今天的分享就到这了,希望能够帮到你呢!😊😊              


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部