java - Java一元提升、左移运算符和short
问题描述
JLS §5.6.1说:
一些运算符将一元数字提升应用于单个操作数,该操作数必须产生一个数字类型的值:
...
如果操作数是编译时类型 byte、short 或 char,则将其提升为 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;
}
}
表达式不(short)1
符合“编译时类型字节、短或字符”的条件吗?
这是我正在使用的:
$ 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)
解决方案
演员在这里是红鲱鱼;没有它,代码编译相同。重要的是表达式1 << 1
是一个常量表达式。所以说JLS(§5.2 ,强调我的):
赋值上下文允许将表达式的值(第 15.26 节)赋值给变量;表达式的类型必须转换为变量的类型。[...] 如果表达式是类型为 、、 或的常量表达式(第 15.28 节) :如果变量的类型是、或,并且常量表达式的值是可表示的,则可以使用缩小原始转换在变量的类型中。
byte
short
char
int
byte
short
char
请注意,您的表达式出现在return
语句中,而不是变量赋值中,但§14.17告诉我们该表达式是赋值上下文,因此上面引用的 §5.2 适用。
所以你有一个类型的赋值上下文short
,并且在那个上下文中你有一个常量表达式1 << 1
,它产生值2
,它确实可以在类型中表示short
。所以这就是它编译的原因。
推荐阅读
- c# - 如何修复 vscode 控制台中的退格自动更正?
- html - 覆盖 HTML/CSS 后面的内容
- android - 如何实现多页面的拖放视图。喜欢这张图片
- android - scrollView.bottom 做什么?
- javascript - React:条件渲染对性能的影响
- unity3d - Imagemagick 翻转通道并创建 alpha 通道(Unreal RMA 到 Unity RMA)
- asp.net-core - 托管 Blazor WebAssembly 应用的本地用户数据库,具有 Azure AD B2C 身份验证
- reactjs - 用于更新数据的 React UseState 钩子 - CRUD
- amazon-web-services - AWS 未能保存预算操作
- java - 如何将活动值传递给片段