【问题标题】:Why can't I assign a final long to an int?为什么我不能将最终的 long 分配给 int?
【发布时间】:2019-10-26 22:25:11
【问题描述】:

据我了解,变量评估是在运行时完成的。然而,在 Java 中,类型评估是在编译时完成的。

正如我所见,将变量设为常量(我使用的是局部变量,但对上述概念没有任何改变),将在编译时使其值已知。

我提供了两个例子来测试这个概念。第一个有效,第二个无效。

有人可以向我解释为什么将变量设为常量允许我将短变量分配给 int 变量,而我不能将 int 变量分配给 long?

// Working example
final int x = 10;
short y = x;

// Non-working example
final long a = 10L;
int b = a;

【问题讨论】:

  • 您不能将 int 设为 long。反之亦然。这与final-声明无关。 final 只表示你不能改变它,它是一个常数
  • 没有从longint 的隐式转换。您需要为分配进行显式转换。
  • @AdrienBrunelat 如果您要回答,请回答我提出的问题。我很清楚不能。我也不能将 int 分配给 short ,不是吗?然而,让它成为最终的(第一个例子)让它工作?!为什么第一个有效而第二个无效。我问的问题很简单。
  • @John 你只对了一半。您的陈述在引用变量方面是正确的,但在原语上它也使它在编译时可见。那么为什么我不能将 10 分配给 int ,因为编译器认为它是 10?
  • @GeorgiVelev 我想我第一次看错了你的问题,但安迪的回答澄清了我的想法。

标签: java variable-assignment final


【解决方案1】:

语言规范的相关部分是JLS 5.2, Assignment Contexts

此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(第 15.28 节):

  • 如果变量是 byte、short 或 char 类型,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换。

使ax 变量final 使它们成为常量表达式(因为它们也是用常量值初始化的)。

第一个示例有效,因为x 是一个常量int,您尝试将其分配给short 变量,并且该值可以在short 中表示;第二个示例不是因为x 是一个常量long,并且您试图将其分配给int 变量(该值是可表示的,但这并不重要,因为它已经不符合隐式缩小转换)。

【讨论】:

  • 第一个示例有效,因为它的最终 int 短 介于 32767 和 -32768 之间(短值范围)。
  • @GeorgiVelev“我不知道我不能保持长期不变”你可以:它仍然是constant expression。你只是不能在这个特定的上下文中使用它。 (例如,如果不是常量表达式,您将无法使用s 作为案例标签in this sample code
  • 这真的回答了这个问题吗?它解释说这是“按规范”而不是错误,但它并没有真正解释为什么它不适用于long,是吗?
  • @tobias_k 对 why 的任何回答都是猜测,除非由参与编写规范的人提供。我会坚持事实来回答;我的 猜测 会是这种行为主要是由于语言中缺少字节/短文字而存在的,因此它消除了分配该类型变量的一点点摩擦;而且,嗯,为什么不将其扩展到所有常量表达式,允许比禁止更容易。但是由于同时存在 long 和 int 字面量,因此最初不需要将 long 提供给 int。但就像我说的:仅仅是猜想。
  • @AndyTurner 这是一个很好的观点,很可能是原因。我认为您可以将其添加到答案中,也许可以加上简短的“免责声明”。相反,如果它被允许,那么int b = 10L 也是合法的,这没有多大意义,而是指向一个问题或错字。
猜你喜欢
  • 2015-12-15
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2017-07-20
  • 2012-11-10
  • 1970-01-01
  • 2019-01-08
相关资源
最近更新 更多