如何解析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)

相关推荐

  • node中如何判断是文件还是文件夹

    技术node中如何判断是文件还是文件夹这篇文章主要介绍node中如何判断是文件还是文件夹,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 在node中,可以利用isFil

    攻略 2021年12月13日
  • 二建考试要求,二级建造师报考的基本要求

    技术二建考试要求,二级建造师报考的基本要求二级建造师报考条件二级建造师考试实行全国统一大纲,各省二建考试要求、自治区、直辖市命题并组织考试的制度,所以报考条件各地也会存在些许的区别,主要都是学历和工作经验等方面的区别,例

    生活 2021年10月22日
  • pulsar消息可靠性(pulsar原理)

    技术Pulsar的特性与优势有哪些这篇文章主要介绍“Pulsar的特性与优势有哪些”,在日常操作中,相信很多人在Pulsar的特性与优势有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

    攻略 2021年12月15日
  • css 背景渐变(如何通过css实现背景颜色渐变?)

    技术css3如何将背景设置为渐变色小编给大家分享一下css3如何将背景设置为渐变色,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

    攻略 2021年12月19日
  • express框架

    技术express框架 express框架Express框架
    Express简化了关于NodeJS应用的开发
    官网地址:https://www.expressjs.com.cn/使用npm instal

    礼包 2021年10月19日
  • Git版本思路是什么

    技术Git版本思路是什么这篇文章给大家介绍Git版本思路是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。简单的说,git的管理策略目前有两大流派。平时和同事聊天或和别的公司的朋友交流时也能够感觉

    攻略 2021年10月20日