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

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

Java反射机制简述

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

 

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

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

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类对象的属性,构造和方法

  

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创建对象

  

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

 

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

  

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方法

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对象,导致可以创建出多个单例对象。

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、方法重载

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

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)的方式关闭安全检查就可以达到提升反射速度的目的
 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李奕赫揍小邰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值