Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过编程证明字符串是否已初始化?_Java_String - Fatal编程技术网

Java 如何通过编程证明字符串是否已初始化?

Java 如何通过编程证明字符串是否已初始化?,java,string,Java,String,尽管日志记录级别设置为INFO,并且在运行时该条件永远不会满足,但我如何通过编程证明“Hi”是否不会初始化 if(log.isDebug()){ log.debug("Hi"); } 我的意思是,由于日志记录级别是INFO,记录器将没有机会打印消息“Hi”,我关心的是,即使条件不满足,我如何确定JRE或JDK是否会采取步骤准备“Hi”。此代码中无需“初始化”;编译器会将字符串文本“Hi”放入.class文件中,因此无论是否实际使用过,它都可以在运行时使用。文本字符串“Hi”是类定义的一

尽管日志记录级别设置为INFO,并且在运行时该条件永远不会满足,但我如何通过编程证明“
Hi
”是否不会初始化

if(log.isDebug()){
    log.debug("Hi");
}

我的意思是,由于日志记录级别是INFO,记录器将没有机会打印消息“Hi”,我关心的是,即使条件不满足,我如何确定JRE或JDK是否会采取步骤准备“Hi”。

此代码中无需“初始化”;编译器会将字符串文本“Hi”放入
.class
文件中,因此无论是否实际使用过,它都可以在运行时使用。

文本字符串“Hi”是类定义的一部分。除非编译器能够确定
的主体(如果
是死代码并且不需要文本),否则当类装入器装入类时,它将装入文本值。因为它是一个编译时常量,所以它也将被自动插入


当类加载到未知的执行环境中时,编译器无法知道
log.isDebug()
的行为。据它所知,记录器类定义可能会更改,以便
isDebug()
返回
true
,而不考虑日志级别的值设置。

我认为字符串文本“Hi”是在堆内存只读中初始化的

您可以使用如下方法计算内存增量:

    if(log.isDebug()){
     log.debug("literal");

     log.debug(memoryUsed());
        log.debug("Hi");
     log.debug(memoryUsed());

     log.debug("initialising");

     log.debug(memoryUsed());
     string x = "Hi"
     log.debug(x);
     log.debug(memoryUsed());
    }


    static long memoryUsed()
      {
      return runtime.totalMemory () - runtime.freeMemory ();
      }

转储字节码。字符串常量将有一个“ldc”操作码。第一次执行操作码是在创建实际字符串时。然后字符串将缓存在常量池中,以便在后续调用/迭代中重用。如果“ldc”从不执行,字符串就不会被创建。

你的意思是
s==null
?我想他的问题是,由于日志级别,Hi将永远不会执行,但他如何证明呢?我仍然不明白你在问什么。字符串文本“Hi”在类加载时由类加载器初始化,因为它是一个文本。你是在问你是否能证明它是否被记录了吗?嗨,泰德,这是否意味着不管记录级别是否正确,字符串文本“Hi”都是由加载类时加载的类初始化的?而这个字符串文字在字符串暂存池中是可能的?字符串“Hi”不会被创建,除非被执行代码引用,至少在任何合理的JVM版本中不会。实际上,字符串值通常不会被创建,除非被引用。字节码中会有一个“加载常量”操作码,第一次执行常量时会从常量池中提取并创建一个字符串对象。因此,该字符串将出现在字节码中,但如果在运行时从未使用其值,则不会加载到内存中。我想你可以称之为“未初始化”。所有字符串都是“只读”的,因为它们是不可变的。“Hi”没有什么特别之处,一旦创建,除了常量池中的字符串外,其他字符串都会被插入,而插入需要用户对用户创建的字符串执行操作。Hi Hot Clicks,我阅读了您的其他评论,您能否对您提到的部分进行扩展实际上,除非被引用,否则通常不会创建字符串值。字节码中会有一个“load CONTANT”操作码,第一次执行该常量时会从常量池中提取,并创建一个字符串对象。每个类都有一个常量池。池的一部分是取自.class文件的不变结构,但另一部分是可以动态更新的表。引用常量字符串时,会检查表(即指针是否为空?)查看是否已创建常量。如果未创建,则将不变结构中的UTF8值扩展为UTF16,并用于创建(并插入)字符串。然后将字符串的指针存储在表中。(至少这是规范JVM中的工作方式,没有对类进行任何特殊处理。)