Reason for casting a static final short to a short?

时间:2015-06-26 10:24:08

标签: java casting short

I came across something that I didn't fully understand earlier and wondering if someone may be able to shed some light on it.

There is a class file with many static final variables, then they're case to the same type as in the declaration and I wonder why.

So as an example we have:

public static final short A_CONST_VALUE = (short)12;

Thanks.

4 个答案:

答案 0 :(得分:1)

虽然 shortint 都是整数原始类型,但它们仍然不相同,并且您的文字 (12) 被默认解释为 {{1} }.

  • int (primitive) 是一个 16 位有符号二进制补码整数,可以存储包含范围 [-215, 215-1];

  • short (primitive) 是一个 32 位有符号二进制补码整数,可以存储包含范围 [-231, 231-1]。

如您所见,int 可以存储比 int 范围更广的值,这意味着 short 不足以存储来自 short 的所有值。

因此,无论何时执行 narrowing primitive conversion,编译器都会执行以下两种操作之一:

  1. 它会在幕后隐式地为您进行转换,IFF 文字值可以适合它所转换到的目标类型的范围。
  2. 它会要求您显式转换类型 IFF 文字值超出您希望它转换到的目标类型的范围。为什么?因为,当文字值超出目标范围时,编译器不确定您希望将值转换为哪种特定类型.. 也许您想将其转换为 int.. 也许转换为 short。 . 所以你必须告诉编译器。
byte

重要了解:

<块引用>

整数类型 byteshortintlong 的值是从 创建的int 文字。

所以,无论何时:

short a = 32767;
//integer literal 32767 will be automatically converted/casted into "short"

short b = 32768;
//Does NOT compile, as 32768 exceeds "short" range and you need to be explicit, about in which type you want it to be casted, because maybe you want to cast it into the "byte", and not into "short"

byte c = (byte) 32768; //compiles, yet overflows the "byte" type

隐式转换适用,并且如果编译器发现字面值超出了目标类型的范围,则无法应用该转换(代码将无法编译),目标类型的范围是您想要用来存储字面值的变量。

P。 S. 在您的示例中,显式转换在语义上是多余的,尽管有些人可能会发现它对语法可读性很好。

答案 1 :(得分:1)

这是多余的。

可能是为了清楚起见而添加的,但在我看来,它没有增加任何价值。

根据JLS § 3.10.1,没有后缀Ll的整数文字是int类型:

<块引用>

一个整数文字是 long 类型,如果它带有一个 ASCII 字母 Ll (ell) 的后缀;否则为 int

类型

因此将 int 转换为 short 需要进行收缩转换。但是,根据 JLS § 5.2,这样的转换是隐式的:

<块引用>

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

  • 如果变量的类型是 byteshortchar,并且常量表达式的值可以用变量。

由于 12 可在类型 short 中表示,因此转换是隐式的。

所以不,演员表是不必要的,我认为无论有没有演员表都会生成相同的字节码,尽管我还没有测试过。

答案 2 :(得分:0)

此行public static final short A_CONST_VALUE = (short)12;没有问题 或public static final short A_CONST_VALUE = 12; 如果您指定的文字在short范围内,即-32,768到32,767。 因此,如果你是这行public static final short A_CONST_VALUE = 32768;并编译,你将得到错误“可能丢失精度:int,required:short”但是如果你写public static final short A_CONST_VALUE = (short)32768;,A_CONST_VALUE的值将被类型转换为{ {1}}它的值将是-32768,即它将循环返回。

因此,只要文字在短范围内,我们就不需要那个类型转换。我们分配给A_CONST_VALUE的文字也不是任何数据类型,只是一个数值,它应该在范围内 - 32,768到32,767因为A_CONST_VALUE是一个短数据表。 Nuts n bolts of primitive datatype in java

答案 3 :(得分:0)

你问为什么有人会这样做:

public static final short A_CONST_VALUE = (short)12;

好吧,我不能代表做这件事的人,但这是不必要的。

让我们解开这个:

  1. public static final 修饰符与此无关。

  2. short 赋值给 short 不应需要强制转换。

  3. 然而......文字1是一个整数文字,它的类型是int而不是short。 (如果它是 1L,那么它的类型就是 long。)。

  4. 通常,将较大类型分配给较小类型(例如 int -> short)确实需要进行类型转换才能执行原始收缩转换.

  5. 但是对于赋值上下文有一个特殊的规则:

    • 如果变量的类型是 bytecharshort
    • AND 分配的值是类型为 bytecharshortint常量表达式的值
    • AND 值在变量类型的范围内....
    • 然后执行隐式原始收缩转换。

在简单的语言中,编译器知道赋值不是有损的,并且在没有您指示的情况下进行转换。

Java 语言规范的相关部分是 JLS 5.2 ... 以 “另外,如果表达式是一个常量表达式...”