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

如果可以在编译时确定Java是否保证内联字符串常量

闻人景澄
2023-03-14
问题内容

考虑这种情况:

public Class1 {
   public static final String ONE = "ABC";
   public static final String TWO = "DEF";
}

public Class2 {

  public void someMethod() {
    System.out.println(Class1.ONE + Class1.TWO);
  }
}

通常,您希望编译器内联ONE和两个常量。但是,是否可以保证这种行为?您是否可以在运行时在类路径中部署不带Class1的Class2,并希望它在不考虑编译器的情况下工作,还是这是可选的编译器优化?

编辑:为什么这样做?好吧,我有一个常量,可以在应用程序的两个端之间共享(通过RMI的客户端和服务器),在这种特殊情况下,将常量放在只能位于该划分的一侧的类上会非常方便(因为从html" target="_blank">逻辑上讲,它是拥有该常量值的对象),而不是仅仅因为它需要代码两边共享而将其包含在任意常量类中。在编译时,它是全部一组源文件,但是在构建时,它是按包划分的。


问题答案:

保证它被视为一个常量表达式,并保证被JLS的15.28节所插入:

编译时常量表达式是表示原始类型或String的值的表达式,该值不会突然完成,并且仅使用以下内容组成:

  • 基本类型的文字和字符串类型的文字(第3.10.5节)
  • 转换为基本类型,转换为字符串类型
  • 一元运算符+,-,〜和!(但不是++或-)
  • 乘法运算符*,/和%
  • 加法运算符+和-


使用String.intern方法,始终将String类型的编译时常量“ interned”,以便共享唯一的实例。

现在,这还不能完全保证可以内联。但是,规范的第13.1节说:

对常量变量字段(第4.12.4节)的引用在编译时解析为表示的常量值。二进制文件中的代码中不应存在对此类常量字段的引用(在包含常量字段的类或接口中,它将具有用于对其进行初始化的代码),并且此类常量字段必须始终看起来已初始化。绝对不能遵守此类字段类型的默认初始值。

换句话说, 即使表达式本身不是常量 ,也不应引用Class1。所以是的,你还好。这并不 一定
保证在字节码中使用级联值,但是前面引用的位保证级联值是interned的,因此如果它不只是内联级联的值,我会感到 非常
惊讶。即使没有,您也可以保证没有它就可以使用Class1



 类似资料:
  • 问题内容: 我发现Java支持原始类型的常量折叠,但是s呢? 例 如果我创建以下源代码 编译后的代码有什么内容? 组合版? 还是效率较低的运行时串联版本? 问题答案: 这是一个简单的测试: 输出: 因此,是的,编译器将折叠。

  • 问题内容: 我正在通过将字符串转换为BSON进行MongoDB查找。在转换之前,有没有办法让我确定我拥有的字符串是否是Mongo的有效ObjectID? 这是我当前的findByID函数的脚本。效果很好,但是如果我确定字符串不是ID,我想按其他属性查找。 问题答案: 我发现猫鼬的ObjectId验证程序可用来验证有效的objectId,但我发现了一些无效ID被视为有效的情况。(例如:任意12个字符

  • 我通过将字符串转换为BSON来进行MongoDB查找。在进行转换之前,是否有办法确定我拥有的字符串是否是Mongo的有效ObjectID? 下面是我当前findByID函数的coffeescript。它工作得很好,但是如果我确定字符串不是ID,我希望通过不同的属性进行查找。

  • 问题内容: 我想知道是否可以在Swift中编写内联汇编。 我知道在Objective-C中,您可以使用如下代码: 但是在Swift中似乎无法使用 。 有谁知道如何使用,如果可能的话。我没有找到任何关于它的信息,所以我认为这是一个很好的问题。 问题答案: 要扩展Robert Levy所说的内容,您可以只使用Swift / Obj-C互操作功能,并编写一个可以处理ASM内容的Obj- C类,然后可以从

  • 问题内容: 如何检查字符串是否已经编码? 例如,如果我编码,我得到。如果我再次对最后一个字符串进行编码,我会得到,如果这样做,我必须先知道它是否已经被编码… 我已经保存了编码参数,我需要搜索它们。我不知道输入参数是什么,要编码还是不编码,所以我必须知道在搜索之前是否必须对它们进行编码或解码。 问题答案: 解码,与原始图像进行比较。如果确实不同,则对原稿进行编码。如果没有区别,则原始文件不会被编码。

  • 问题内容: 我正在尝试确定字符串数组中的特定项目是否为整数。 我是形式上的中缀表达式,然后尝试将结果数组拆分为两个数组;一个用于整数,一个用于运算符,同时丢弃括号和其他杂项。做到这一点的最佳方法是什么? 我以为我也许可以找到一种方法或某种方法,但是没有运气。 问题答案: 最幼稚的方式是遍历String并确保所有元素对于给定的基数都是有效数字。由于你必须至少查看一次每个元素,因此这将尽可能地提高效率