当前位置: 首页 > 知识库问答 >
问题:

Java一元提升、左移位运算符和short

薛墨一
2023-03-14

JLS§5.6.1规定:

一些运算符将一元数值提升应用于单个操作数,该操作数必须产生数值类型的值:
...
如果操作数是编译时类型的字节、短或字符,则通过拓宽将其提升为int类型的值在以下情况下,对表达式执行一元数字提升:
...
移位运算符的每个操作数分别

这就解释了该程序无法编译的原因:

public class xx {
    public short twice(short x) {
        return x << 1;
    }
}

有了这个错误:

$ javac xx.java
xx.java:3: error: incompatible types: possible lossy conversion from int to short
        return x << 1;
                 ^
1 error

好的。那么为什么这个程序编译成功呢?

public class xx {
    public short two() {
        return (short)1 << 1;
    }
}

表达式(短)1是否符合编译时类型byte、短或char的条件?

以下是我正在使用的:

$ java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-bre_2021_01_20_16_37-b00)
OpenJDK 64-Bit Server VM (build 25.282-b00, mixed mode)

共有2个答案

易阳朔
2023-03-14

演员在这里是转移注意力的;没有它,代码编译也是一样的。重要的是表达式1

赋值上下文允许将表达式的值赋值(§15.26)给变量;表达式的类型必须转换为变量的类型。[...]如果表达式是类型为bytecharint的常量表达式(§15.28):如果变量的类型为byte,或char,并且常量表达式的值可以在变量的类型中表示。

请注意,您的表达式出现在return语句中,而不是在变量赋值中,但§14.17告诉我们该表达式是赋值上下文,因此上文引用的§5.2适用。

因此,您有一个类型为short的赋值上下文,在该上下文中,您有一个常量表达式1

冉绯辞
2023-03-14

我创建了与您的类似的示例代码,然后检查了字节码。代码如下:

package dsa;

public class Shorts {

    public static void main( String[] args ) {
        short what = twice();
        System.out.println(what);
    }
    
    public static short twice() {
        return 1 << 1;
    }
    
}

以及生成的字节码:

Compiled from "Shorts.java"
public class dsa.Shorts {
  public dsa.Shorts();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #7                  // Method twice:()S
       3: istore_1
       4: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;
       7: iload_1
       8: invokevirtual #19                 // Method java/io/PrintStream.println:(I)V
      11: return

  public static short twice();
    Code:
       0: iconst_2
       1: ireturn
}

请注意,我不是专家,但在我看来,编译器优化函数返回常数整数,然后将其存储在int变量中,直到打印出来。所以答案是,套用一部著名电影中的一句话:“没有短片”。

 类似资料:
  • 问题内容: 在PHP手册中,我在“操作员”下找到以下“用户提供的说明 ”。 请注意,在php中,三元运算符?:具有左联想性,与C和C ++中具有右联想性的情况不同。 您不能编写这样的代码(就像您在C / C ++中所习惯的那样): 我实际上尝试过,它确实可以打印。但是我不明白它背后的原因,仍然觉得它应该打印或显示。 有人可以解释一下这里发生了什么以及为什么打印“四个”吗? 问题答案: 在任何理智的

  • 主要内容:位逻辑运算符,位移运算符,复合位赋值运算符Java 定义的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括 long,int,short,char 和 byte。 位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值。 Java 语言中的位运算符分为位逻辑运算符和位移运算符两类,下面详细介绍每类包含的运算符。 位逻辑运算符 位逻辑运算

  • 问题内容: 当遇到按位移位运算符时,我遇到了一个有趣的场景。如果第二个操作数为负,按位移位运算如何工作?。 即,<< << b,“ <<”将a中的位模式向左移动b位。但是,如果b为负数,在运行时是否应该出错? 我能够成功运行以下代码,但我不知道它是如何工作的? 输入项 结果 “ a”的ASCII码为97。有人可以帮助我了解其工作原理吗? 问题答案: 但是,如果b为负数,在运行时是否应该出错? 不符

  • 问题内容: 我正在尝试了解轮班经营者,但收获不多。当我尝试执行以下代码时 我得到以下 有人可以解释一下吗? 问题答案: 将二进制2()向左移动11次。因此:1000000000000 将二进制2()向左移动22次。因此: 现在,int为4字节,因此为32位。因此,当你偏移33时,它等效于偏移1。因此:100

  • 问题内容: 您能否解释一下为什么使用第一个返回类型无法编译代码?消息是:。 在第二种情况下是否插入了显式强制转换? 问题答案: 由于类型推断规则。我不知道为什么要 这么做 (您应该检查JSL 的三元运算符部分),但是看来三元表达式不能从返回类型推断出类型参数。 换句话说,三元表达式的类型取决于其操作数的类型。但是其中一个操作数的类型参数()不确定。那时三元表达式仍然没有类型,因此它不会影响类型参数

  • 问题内容: 是否可以更改此: …对三元运算符? 问题答案: 好吧,中的行为就像这样…… …另一种看待它的方式… 你的问题有点含糊,我们必须在这里假设。 如果(且仅当)声明了一个返回值(,等。)-现在看来似乎没有做到这一点通过你的代码-那么你可以做到这一点… 如果callFunction(…)不返回值,那么你将无法使用三元运算符!就那么简单。你将使用不需要的东西。 请发布更多代码以清除所有问题 尽管