为什么混合+和强制转换不会在"+(int)+(long)-1"中产生错误?

Pra*_*dey 53 java

为什么打印1?

import java.util.*;
import java.lang.*;
import java.io.*;


class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        // your code goes here
        System.out.println((byte)+(short)-(int)+(long)-1);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以混合铸造和+,-一元操作员吗?我知道我们可以多次进行转换,但为什么不让+ ,-一元运算符产生错误呢?

Pac*_*ato 81

你不是在增加或减少.那些+和 - 运算符是一元符号运算符.

文档一元运算符节.

利害攸关的顺序:

(byte)+(short)-(int)+(long)-1
Run Code Online (Sandbox Code Playgroud)

从右到左进行评估,如下所示:

初始值是-1
铸造到长(仍然是-1)
一元+符号(仍为-1)
铸造到int(仍然-1)
一元 - 符号(现在值为1)
等等(值保持为1直到结束)


joh*_*902 39

这些+-是一元的.

更具体地说,它实际上是:

System.out.println((byte) (+((short) (-((int) (+((long) -1)))))));
Run Code Online (Sandbox Code Playgroud)

  • 哇那里,Java从什么时候成为Lisp?:) (13认同)
  • @Dukeling他回答后编辑了他的问题.最初使用"标志"而不是"一元运算符". (3认同)

Wii*_*axx 12

如果从示例中删除所有强制转换,因为在这种情况下它将不执行任何操作

System.out.println((byte)+(short)-(int)+(long)-1);

会变成

System.out.println( + - + -1);

现在你可以看到只有运算符仍在那里,因为减号和减号都是加号,你的结果将是1

基本上你可以这样想:

var mylong  = +(long)-1;      <- -1
var myint   = -(int)mylong;   <-  1
var myshort = +(short)myint;  <-  1
var mybyte  =  (byte)myshort; <-  1
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 7

我知道我们可以做多次铸造.但是将两个一元运算符放在两者之间不会产生错误?

这只是Java语法一致性的结果.当你写作

+ 1
Run Code Online (Sandbox Code Playgroud)

你实际写的是一个一元数字表达式,它分解为两部分:

  1. 一元加运算符: +
  2. 一个数值表达式,在这种情况下,int文字1.

数值表达式的另一个示例是强制转换表达式(也是一元):

(int) 1
Run Code Online (Sandbox Code Playgroud)

因此,您可以将其替换为上述原件1:

+ (int) 1
Run Code Online (Sandbox Code Playgroud)

重复相同的一致过程,我们最终会得到任意复杂性的嵌套一元表达式.要回到您的关键问题:

为什么?

因为Java实际上需要针对此类表达式的特定规则.