Java反射机制详解与使用方法大全!!!

news/2024/5/19 6:19:04 标签: java, 开发语言, 反射

❤ 作者主页:李奕赫揍小邰的博客
❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~*
🍊 记得点赞、收藏、评论⭐️⭐️⭐️
📣 认真学习!!!🎉🎉

文章目录

  • Java反射机制简述
  • 1、四种方式获取Class类的对象
  • 2、获取class类对象的属性,构造和方法
  • 3、使用newInstance创建对象
  • 4、通过Constructor对象调用无参和有参方法
  • 5、使用反射动态调用有无参有无返回值的Method方法
  • 6、反射会破坏OOP对象
  • 7、方法重载
  • 8、setAccessible的作用

Java反射机制简述

  Java反射机制的核心时在程序运行时动态加载类并获取类的详细信息,从而可以调用类或对象的属性和方法。
  它的本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象和类的各种信息。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

 

1、四种方式获取Class类的对象

  
前置:新建一个UserInfo实体类在com.jjl.domain下面
在这里插入图片描述

java">Class class1= UserInfo.class;
Class class2=new UserInfo().getClass();
Class class3=UserInfo.class.getClassLoader().loadClass("com.jjl.domain.UserInfo");
Class class4=Class.forName("com.jjl.domain.UserInfo");

 

2、获取class类对象的属性,构造和方法

  

java">public static void main(String[] args) {    
Class userInfoClass= UserInfo.class;    //属性列表    
Field[] a=userInfoClass.getDeclaredFields();      
//getFields()方法获取类的全部公共字段,getDeclaredFields()方法获取全部字段    
for(Field field:a){        
	System.out.println(field.getName());    
}    
//构造列表    
Constructor[] b=userInfoClass.getConstructors();    
for(Constructor constructor:b){        
	System.out.println(constructor.getName());    
}    
//方法列表    
Method[] c=userInfoClass.getDeclaredMethods();    
for(Method method:c){        
	System.out.println(method.getName());    
}}

 

3、使用newInstance创建对象

  

java">//不用new来创建对象,原理就是反射技术
String newObjectName="com.jjl.domain.UserInfo";
Class class4=Class.forName(newObjectName);
//newInstance开始创建对象
UserInfo userInfo=(UserInfo) class4.newInstance();

 

4、通过Constructor对象调用无参和有参方法

  

java">String newObjectName="com.jjl.domain.UserInfo";
Class class4=Class.forName(newObjectName);
Constructor constructor1=class4.getDeclaredConstructor();     //调用无参方法
UserInfo userInfo1=(UserInfo) constructor1.newInstance();
System.out.println(userInfo1.hashCode());
Constructor constructor=class4.getDeclaredConstructor(long.class,String.class,String.class);  //调用有参方法
System.out.println(constructor.newInstance(11,"a1","aa1").hashCode());
System.out.println(constructor.newInstance(12,"a2","aa2").hashCode());    //结果下图

 

5、使用反射动态调用有无参有无返回值的Method方法

java">String newObjectName="com.jjl.domain.UserInfo";
Class class4=Class.forName(newObjectName);
UserInfo userInfo=(UserInfo) class4.newInstance();
String methodName="test";
//调用无参无返回值的Method方法
Method method=class4.getDeclaredMethod(methodName);
System.out.println(method.getName());
method.invoke(userInfo);     //根据获取的方法,反射执行该方法  getName()获取名称,invoke()反射执行
//调用有参无返回值的Method方法
Method method=class4.getDeclaredMethod(methodName,String.class);
System.out.println(method.getName());
method.invoke(userInfo,"我的地址在北京");
//调用有参有返回值的Method方法
Method method=class4.getDeclaredMethod(methodName,Integer.class);
System.out.println(method.getName());
Object returnValue=method.invoke(userInfo,99999);
System.out.println("returnValue"+returnValue);

 

6、反射会破坏OOP对象

  单例模式由于构造方式式private的,不能new实例化对象,只有调用getOneInstance()获取自身对象,而且可以保证单例。但是使用反射技术能破坏OOP对象,导致可以创建出多个单例对象。

java">OneInstance o1=OneInstance.getOneInstance();    //单例模式(饱汉式) 保证当前进程只有一个实例对象
OneInstance o2=OneInstance.getOneInstance();
OneInstance o3=OneInstance.getOneInstance();
System.out.println(o1);
System.out.println(o2);
System.out.println(o3);
Class classRef=Class.forName("com.jjl.objectfactory.OneInstance");   //从这里开始使用反射实例化对象
Constructor c=classRef.getDeclaredConstructor();
c.setAccessible(true);
OneInstance one1=(OneInstance) c.newInstance();
OneInstance one2=(OneInstance) c.newInstance();
System.out.println(one1);
System.out.println(one2);

执行结果:
在这里插入图片描述

 

7、方法重载

  使用反射可以调用重载方法

java">public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    Class class15=Test15.class;
    Object object=class15.newInstance();
    Method method1=class15.getDeclaredMethod("testMethod", String.class);
    Method method2=class15.getDeclaredMethod("testMethod", String.class,String.class);
    method1.invoke(object,"法国");
    method2.invoke(object,"中国","中国人");
}
public void testMethod(String username){
    System.out.println("public void testMethod(String username)");
    System.out.println(username);
}
public void testMethod(String username,String password){
    System.out.println("public void testMethod(String username,String password)");
    System.out.println(username+" "+password);
}

 

8、setAccessible的作用

  setAccessible功能是启用或禁用安全检查;具体的用处主要有两处,作用于方法上,method.setAccessible(true);作用于属性上field.setAccessible(true);
  将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查;实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问 ;
  由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
 



http://www.niftyadmin.cn/n/4927261.html

相关文章

维护工程师提升设备管理水平的5个技巧

维护在工业工厂中扮演着至关重要的角色,而在这一关键领域,维护工程师发挥着关键作用。无论是混合还是离散自动化产线,设备的正常运行和保养对于确保生产的持续性至关重要。为了实现高效、成功的维护,维护工程师需要采取一系列方法…

Linux Shell 编程入门

从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天…

WordPress主题开发 — 模版循环(条件判断、多个循环、新建查询和文章循环)

循环是 WordPress 通过主题模板文件输出文章的默认机制 。在循环中,WordPress 遍历当前页面获取到的所有文章,然后使用主题中的模版标签将其格式化并输出。 我们可以用 WordPress 循环来做很多事情,例如: 在网站首页显示多个文章…

【图像去噪的扩散滤波】基于线性扩散滤波、边缘增强线性和非线性各向异性滤波的图像去噪研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

每日后端面试5题 第三天

1. 线程有哪几种状态以及各种状态之间的转换?(必会) 看图: 图片来自 线程状态转换图及其5种状态切换_小曹的blog的博客-CSDN博客 图片来自 总算把线程六种状态的转换说清楚了! - 知乎 线程一共有4种状态,分别是: 1.…

【数据库】Redis可以替代Mysql吗

Redis和Mysql的搭配 Redis可以替代Mysql吗什么是RedisRedis适用的场景以及优点Redis的缺点 什么是MysqlMysql的优点Mysql缺点 总结 Redis可以替代Mysql吗 Redis不能代替MySQL, Redis和MySQL只能是一种互补。 什么是Redis Redis是一种非关系型数据库,也…

CSS:background 复合属性详解(用法 + 例子 + 效果)

目录 background 复合属性background-color 背景颜色(纯)background-image 背景图片 或者 渐变颜色background-repeat 背景是否重复background-size 设置图片大小background-position 设置背景图片显示位置background-attachment 设置背景图片是否随页面…

如何使用Mac终端给树莓派pico构建C/C++程序进行开发,以及遇到各种问题该怎么处理,不使用任何IDE或编辑器(例如VS Code)

写本文的原因是官方的教程已经过时了,如果你现在按照官方教程来在 Mac 上进行配置,那么会遇到一堆问题,比如我几乎把能踩的“雷”都踩了。所以这里记录了完整过程,以及各种错误的原因和处理方法,不然以后换 Mac 了或者…