如何解析Java常量池与字符串intern

技术如何解析Java常量池与字符串intern这期内容当中小编将会给大家带来有关如何解析Java常量池与字符串intern,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在Java应用程

本期,边肖将为大家带来关于如何分析Java常量池和字符串实习生的信息。文章内容丰富,将从专业角度进行分析和描述。希望你看完这篇文章能有所收获。

Java应用运行时,Java虚拟机保持一个内部运行时常量池,它不同于类文件的常量池,是类文件的常量池映射到虚拟机的数据结构。

1.CONSTANT_Class入口解析

数组的符号解析是特殊的。如果它是基本类型的数组,那么虚拟机将创建一个基本类型的新数组Class,并创建一个类实例来表示该类型。数组类的定义类加载器是启动类加载器。如果是引用类型的数组,则在此之前解析引用类型,数组类的定义类加载器就是引用类型的定义类加载器。

非数组类和接口的的解析将经历以下步骤:

(1).加载该类型及其所有超类型。

如果之前已经将该类型加载到虚拟机的当前命名空间中,则可以直接使用加载的类型;否则,它将被引用的初始类的初始类加载器加载。目标类型的超类的加载必须基于当前类型的加载,因为只有在当前类型的加载之后,才能从类文件的super_class字段中找到其直接超类的符号引用,然后递归分析加载,直到java.lang.Object类。在递归返回的过程中,检查interfaces域以查看实现或扩展了哪些接口,并再次递归遍历对接口的符号引用。

(2).检查访问权限

然后是目标类型的连接和初始化,这样该类型就可以正常使用了。如前所述,目标类型的初始化要求其所有超类都必须被初始化(超接口不是必需的),并且由于其超类已经被加载,因此不再需要依赖从类到对象类的解析顺序,而是从对象类到类的初始化。连接和初始化类型的步骤如下:

(3).类型检查

(4).类型准备

(5).类型解析(可延期)

请注意,这个过程是对被引用类型及其超类的符号引用的分析,因为引用类型的一些符号引用不会立即使用,所以这个步骤是对严格启动引用的类型进行符号分析的过程。只有当主动使用被引用类型的这些符号引用所指向的类型时,这些符号引用才会被解析,它们所指向的类型才会被加载、连接和初始化。

(6).类型初始化

2.CONSTANT_Fieldref入口解析

由于一个类型不包含由其超类定义的字段,因此对目标字段的搜索将从该字段指向的类型开始,然后递归搜索它实现或扩展的接口,然后递归搜索它的超类,直到找到目标字段。运行时常量池中该字段的条目将被标记为已解析,并且该常量池的数据将被更改为对该字段的直接引用。

3.CONSTANT_Methodref入口解析

类似于但不同于字段搜索,它的搜索顺序将从类型开始,然后递归搜索它的超类,并递归搜索它的实现或扩展接口。

4.CONSTANT_InterfaceMethodRef入口解析

搜索接口的方法是从被分析的接口开始,递归搜索它的超级接口。

5.CONSTANT_String入口解析

Java虚拟机将字符串视为要维护的字符串对象,但是虚拟机维护的是一个字符串池,其中包含所有被保留的字符串对象的引用。要分析CONSTANT_String常量池,我们必须首先检查字符串池中字符串对象的引用是否存在。如果是这样,我们可以直接将常量池数据分析成字符串对象的引用。如果没有,我们需要根据字符串序列创建一个字符串对象,将其引用添加到字符串池中,并将常量池数据分析到引用中。

您也可以使用字符串对象的实习对象来扣留字符串(请注意,它不是字符串对象)。如果字符串池中有对字符串序列对象的引用,直接返回引用即可;否则,字符串将被扣留,但请注意,扣留返回的字符串对象的引用不会指向原始字符串对象,因为原始字符串对象位于Java堆中,字符串池的对象由虚拟机创建和维护。

packagecom.ice .实习生;public class intertest { publicationstativitmain(Strings[]){ Stringa=NewString(‘ 123 ‘);string b=a;(=NationalBureauofStandards)国家标准局

p;    String c = new String("123");;          System.out.println("before intern:");         System.out.println("a = b ? :" + (a == b));         System.out.println("a = c ? :" + (a == c));          a = a.intern();         c = c.intern();          System.out.println("after intern:");         System.out.println("a = b ? :" + (a == b));         System.out.println("a = c ? :" + (a == c));     }  }

结果如下:

如何解析Java常量池与字符串intern

(6).其他类型(数据基本类型)入口解析

直接使用常量池所包含的常量值即可

6.直接引用

常量池解析最终将符号引用替换成为直接引用。指向类型、类变量和类方法的直接引用可能为在方法区的指针。而指向实例变量和实例方法的直接引用是从对象映像的开始到该实例变量或方法表的偏移。

实例变量的组织方式为:从Object类开始到该实例的类型,将类中声明的实例变量按在class文件中出现的顺序依次放在对象映像中。
实例方法的组织方式较为类似:从Object类开始到该实例的类型,将类中声明的实例方法指针按在class文件中出现的顺序依次放在对象映像中。但对于重写的方法将出现在超类对应的位置(该方法***次出现的位置)。

但是访问接口方法就不能简单地通过方法表的偏移量来进行访问,而必须搜索对象的类的方法表来找到该方法。

比如Factory接口分别由A和B来实现其produce()方法,但由于A和B不能保证由同一个实现了Factory接口的超类派生,即有着同样的produce()方法偏移,那么就无法通过方法表的偏移来访问Factory的produce()方法。

7.装载约束

对于一个类型指向另一个类型的符号引用,如果引用的类型和被引用类型并非由同一个初始加载器加载(可能通过用户自定  义ClassLoader来实现),那么虚拟机就必须确保被引用类型在不同的命名空间中保持一致。这样就通过自定义ClassLoader来加载不受信类   型后,就不会发生解析对被引用类型的符号引用时,把受信的类型当做已经被解析过的不受信类型(因为对方法的符号引用只有权限定名和描述符,并不会也无法得  知其初始类加载器),从而调用了不受信类型的方法访问受信类型的受保护成员。

如何解析Java常量池与字符串intern

上述就是小编为大家分享的如何解析Java常量池与字符串intern了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/112489.html

(0)

相关推荐

  • C# PowerPoint中如何添加、修改和删除动画

    技术C# PowerPoint中如何添加、修改和删除动画小编给大家分享一下C# PowerPoint中如何添加、修改和删除动画,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获

    攻略 2021年11月19日
  • 23种设计模式,三)抽象工厂模式

    技术23种设计模式,三)抽象工厂模式 23种设计模式(三)抽象工厂模式简要概括23种设计模式之抽象工厂模式三、抽象工厂模式
    ? 前面介绍的工厂方法模式中考虑的是一类产品的生产,如汽车厂商生产汽车,手机

    礼包 2021年11月23日
  • 视觉皮层的架构

    技术视觉皮层的架构 视觉皮层的架构视觉皮层的架构
    卷积神经网络(CNN)起源于对大脑的视觉皮层的研究,从20世纪80年代起被用于图像识别。在过去几年中,由于计算机计算能力的提高、可训练数据数量的增加,以

    礼包 2021年11月14日
  • 苹果手机如何删除通讯录联系人,苹果id怎么删除电话号码

    技术苹果手机如何删除通讯录联系人,苹果id怎么删除电话号码苹果手机删除电话号方法苹果手机如何删除通讯录联系人: 以iPhone8手机为例,删除“联系人”(电话号码)有如下操作: 一、在手机桌面打开“电话”。
    二、打开“

    生活 2021年10月22日
  • 如何实现VB.NET文件流读、写类文件

    技术如何实现VB.NET文件流读、写类文件这篇文章主要介绍如何实现VB.NET文件流读、写类文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!VB.NET文件流代码:Option Explicit

    攻略 2021年12月2日
  • 日本服务器租用哪家服务比较好

    技术日本服务器租用哪家服务比较好在租用日本服务器的时候首先要选择合适的机房才能确保服务器的正常稳定运行,那么如何判断自己选择的机房是否可靠呢,日本服务器租用哪家售后服务比较好,建议考察一下以下几点服务器维护 定期进行服务

    礼包 2021年12月16日