java中的反射机制(通过反射验证单例模式不是jvm安全的)

一、首先我们了解一下类的加载过程
1.加载:类加载器使用“双亲委托”模型在指定的类路径下搜索相应的class字节码文件,从class字节码文件内容生成类的Class对象。
2.链接:验证字节码文件的合法性,是否能在当前JVM版本环境下运行,为类的静态域分配内存空间,如果当前类引用了其它类,则继续解析对其它类的引用。
3.初始化:执行静态成员变量和静态块的初始化。
我们可以看出,在一个类刚开始进行加载的时候,从class字节码文件内容生成类的Class对象。在Java语言中,万事万物皆对象,类也是对象,它是Class类的实例对象。当我们开始加载它时,就相当于新建了一个Class类的实例对象。
通常我们都是通过new新建一个对象(在构造函数不为私有的情况下),而Class类中构造函数为私有,在类的外部是不可以直接访问的。
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第1张图片
二、不能通过new去新建实例对象,那该如何去表示这个实例对象?
此时,就引出了java中的反射机制(从java 1.2开始引进):
Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法;对于给定的一个对象,都能够调用它的任意一个属性和方法。这种动态获取类的内容以及动态调用对象的方法称为反射机制。
①.已知该类的类名:
Class c=neil.class; //我们可以通过类名.class去获取类的类类型,也相当于类的身份信息。即每个类都包含一个隐含的静态成员变量
②已知该类的对象:

neil n=new neil();
Class c1=n.getClass();

③直接通过Class.forName(“类的全称”)来获取
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第2张图片
因为一个实例对象表示的是一样的信息,所以此时三种方式表示的类类型是相同的:
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第3张图片
运行结果:
在这里插入图片描述
三、当我们拿到一个人的身份证就可以知道它的一些个人信息,而此时我们就相当于拿到了这个类的“身份证”,我们不需要通过直接询问本人来获取个人信息,可以自己去查看,从而间接获得。
身份证上有姓名年龄等,一个类中我们可以看到:
①成员变量------->属性 field
②构造函数------->初始化 constructor
③成员方法------->方法 method
1>我们可以看出,获取构造函数时,有四种。有s的是返回一个数组,即所有的构造方法,没有s的则返回单个。
而加了Declared为返回所有的包括访问权限为私有的构造方法,不加的只返回权限为public的构造方法。
后边需要传入参数列表的是返回指定参数类型的构造方法。
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第4张图片
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第5张图片
2>获取成员变量
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第6张图片
调用DeclaredFields()获取的是所有的成员变量包括私有的
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第7张图片
运行结果:
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第8张图片
在这里插入图片描述
3>获取类的成员方法
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第9张图片
来获取它的所有的成员方法,包括私有的:
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第10张图片
运行结果:java中的反射机制(通过反射验证单例模式不是jvm安全的)_第11张图片

java中的反射机制(通过反射验证单例模式不是jvm安全的)_第12张图片
反射机制不仅可以间接访问类的静态成员和类对象的实例成员和成员方法,还可以通过

         Class c=Singleton.class;  //获取类的类类型,即类的信息
         Constructor con=c.getConstructor(null) ;  //获取无参的构造方法
         con.setAccessible(true);//修改访问权限

在学习单例模式的时候我们知道,创建单例模式的必要条件之一就是私有化构造函数,而通过反射机制我们可以突破私有构造

         Singleton s=con.newInstance();   //通过newInstance()方法创建单例实例

创建多个单例实例。
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第13张图片
此时运行s1==s2;//运行结果为false;
在这里插入图片描述
通过反射机制,我们可以知道单例模式并不是jvm安全的,我们相当于拿到了权限卡,拥有高一级别的权限。----->我们可以通过枚举(已从jvm中防止反射机制,没法实例化)产生一个jvm和线程安全的单例模式。
java中的反射机制(通过反射验证单例模式不是jvm安全的)_第14张图片
运行结果:
在这里插入图片描述
java的反射机制有什么作用呢

Java的反射机制允许编程人员在对类未知的情况下,获取类相关信息的方式变得更加多样灵活,调用类中相应方法,是Java增加其灵活性与动态性的一种机制

你可能感兴趣的:(java中的反射机制(通过反射验证单例模式不是jvm安全的))