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

为什么null不为编译时间常数?

萧波峻
2023-03-14
问题内容

因此,如果我有一个static final Object CONSTANT = null,由于某种原因,如果我在另一段代码(如)中引用它doSomething(CONSTANT),则在编译过程中它不会内联到代码中。因此doSomething(null),它不是在被编译之后而是doSomething(CONSTANT)


问题答案:

CONSTANT不是编译时间常数,因为JLS 表示 不是。只能在常量表达式中使用的类型是基本类型和String

它的意义是,一个Object实例(通常)具有语义上重要的对象标识,该标识将其与其他Object实例区分开。此对象标识不能编码在类文件中……至少,不能用当前的类文件格式编码。(如果可能的话,还会有各种各样的其他问题……)

该值null(理论上)可以作为特殊情况处理,除非没有太多意义。具体而言,null从语言的角度来看,您不能在需要(或有利)“编译时间常数”的任何上下文中使用。例如:

  • 你不能有null这样的case表达。
  • 由于==引用类型不是常量表达式,因此您不能将其用于涉及if以常量表达式为条件的Java“条件编译”惯用语。(而且null == null不是一个有用的条件…)

就内联而言,虽然不能在字节码中内联“常量”(因为有关“常量表达式”的JLS规则),但允许JIT编译器的优化器执行此操作,并且实际上 可以
这样做…如果有明显的绩效收益。

参考:

  • JLS 15.28-常量表达式


 类似资料:
  • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用

  • 我有一个简单的测试设置,如 但当我尝试编译测试时,我会遇到53个错误,比如 实际上并没有传达任何关于问题所在的有用信息。我只能假设在我的构建中没有正确配置某些内容。sbt文件或其他地方。 这段代码确实曾经工作过,在我清理东西的过程中,事情发生了变化,现在它被破坏了,没有好的诊断。 有人能提出要找的东西吗?

  • 我创建了一个从HashMap中删除学生的方法。当id为NULL时,它会抛出一个异常。有人知道它为什么不起作用吗? 公共类应用程序{public static void main(String[]args){ }

  • 问题内容: 我们知道throw的规则是,其中必须是Throwable类型的对象或Throwable的子类。 简单类型(例如int或char)以及不可Throwable类(例如String和Object)不能用作异常。是表示空值的特殊Java文字。 那么为什么要在此代码中进行编译? 问题答案: 根据语言规范,一条语句定义为: 如果计算结果为,则抛出a。特别, 如果对 Expression的 求值正常

  • 问题内容: 如果你给 它没有编译,但是带有花括号的相同代码是: 有什么解释? 问题答案: 基本上,变量声明只能在块中声明。 查看 Java语言规范中“语句”的语法 -它包括Block,但不包括LocalVariableDeclarationStatement- 后者是block语法的一部分。 这实际上是实用主义的问题:如果没有括号,则只能使用一个语句。如果没有后续语句,则声明变量是没有意义的,因为