理解缩小原始转换

use*_*882 1 java

我试图理解Java中缩小的原始转换概念.以下是JLS 5.1.3对此的说法:

原始类型的22个特定转换称为缩小基元转换:

短到字节或字符

char到byte或short

int到byte,short或char

long to byte,short,char或int

float to byte,short,char,int或long

double to byte,short,char,int,long或float

由于是隐式转换转换longint,我们可以写出下面的代码:

public static void main (String[] args) throws java.lang.Exception
{
    int c = 88L; //Compilation fail
    System.out.println(c);
}
Run Code Online (Sandbox Code Playgroud)

DEMO

但它不起作用.为什么?应该应用从long到int的缩小转换.

Jon*_*eet 6

由于存在将long转换为int的隐式转换

没有.有明确的转换.缩小转换通常不会隐式应用,正是因为它们可能会丢失信息.所以你需要:

int c = (int) 88L;
Run Code Online (Sandbox Code Playgroud)

实际上,JLS第5节初始部分甚至给出了一个例子:

// Casting conversion (5.4) of a float literal to
// type int. Without the cast operator, this would
// be a compile-time error, because this is a
// narrowing conversion (5.1.3):
int i = (int)12.5f;
Run Code Online (Sandbox Code Playgroud)

有一些情况下,收缩转换在明确应用分配上下文(JLS 5.2) ,但:

此外,如果表达式类型的常量表达式(§15.28) ,byte,short,charint:

  • 如果变量的类型是byte,, short或者char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示.

  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:

    • Byte并且常量表达式的值可在类型中表示byte.

    • ...(类似于ShortCharacter)

这就是为什么是即使字面的类型有效的120int:

byte x = 120;
Run Code Online (Sandbox Code Playgroud)

将其与扩展转换进行比较,这些转换在赋值上下文调用上下文中是允许的(JLS 5.3).