当前位置: 首页 > 面试题库 >

了解常量池的javap输出

薛滨海
2023-03-14
问题内容

在非常简单的HelloWorld应用程序上运行javap时,我对常量池周围的输出有些困惑。

测试代码

public class TestClass {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Javap -c -verbose输出(已删除)

// Header + consts 1..22 snipped
const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #22; //String hello world
   5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return
  // Debug info snipped
}

好的,因此在第3行上,我们通过#22看到将“ hello
world”常量推入堆栈,但是const#23似乎保留了实际值。我想我对#(数字)出现在打印输出的右侧时的含义有些困惑。

Oracle /
Sun的javap手册页还有
很多不足之处。


问题答案:

你所有的classinterfacefield名称和string常量进入java的 常量池

根据VM规范(http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):

constant_pool是一个结构表(第4.4节),表示各种字符串常量,类和接口名称,字段名称以及在ClassFile结构及其子结构中引用的其他常量。每个constant_pool表条目的格式由其第一个“标签”字节指示。constant_pool表的索引从1到constant_pool_count-1。

因此,就常量池而言,可以将以下内容视为:

const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

#22(索引22)处的String值是类型,其值为null终止的c字符串(Asciz)hello world位于索引23。



 类似资料:
  • 本文向大家介绍Java 常量池的实例详解,包括了Java 常量池的实例详解的使用技巧和注意事项,需要的朋友参考一下 Java 常量池的实例详解 Java的常量池中包含了类、接口、方法、字符串等一系列常量值。常量池在编译期间就已经确定,并保存在*.class文件中 一、对于相同的常量值,常量池中只保存一份拷贝。 而且,当一个字符串由多个字符串常量链接而成时,多个字符串被组成一个字符串常量。 例如:

  • 本文向大家介绍Java 中的字符串常量池详解,包括了Java 中的字符串常量池详解的使用技巧和注意事项,需要的朋友参考一下 Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new String("droid");,这两种方式我们在代码编写时都经常使

  • 如这些问题中所述:问题1 在以下情况下,JVM将创建一个新的字符串对象,而不是使用字符串池中的现有对象: 然而,在阅读了下面两个类似的陈述之后,我有一个疑问。 从SCJP准备书: 当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。如果找到匹配项,对新文本的引用将指向现有的String,并且不会创建新的String文本对象。 来自JavaRanch: 在本例中,由于关键字“new”,我

  • 本文向大家介绍浅谈java常量池,包括了浅谈java常量池的使用技巧和注意事项,需要的朋友参考一下 java常量池技术 java中常量池技术说的通俗点就是java级别的缓存技术,方便快捷的创建一个对象。当需要一个对象时,从池中去获取(如果池中没有,就创建一个并放入池中),当下次需要相同变量的时候,不用重新创建,从而节省空间。 java八种基本类型的包装类和对象池 java中的基本类型的包装类、其中

  • 问题内容: 我想我需要更好地了解连接池的概念。我正在使用Java与ConnectorJ一起工作,并将servlet部署在Apache Tomcat服务器上。我一直在关注该文档,因此我的Tomcat context.xml如下所示: 我使用推荐的方式从数据源获得连接: 我的问题是:为什么我必须在context.xml中为我的数据源指定用户和密码。如果我错了,请纠正我,但我认为连接池的重点是重用拥有相