Java 为什么入门书中定义的关于类型转换和算术运算符的规则似乎有冲突?

Java 为什么入门书中定义的关于类型转换和算术运算符的规则似乎有冲突?,java,operators,typecasting-operator,Java,Operators,Typecasting Operator,我最近通过一本面向编程初学者的书开始学习java。关于类型转换和算术运算符的两条规则似乎在逻辑上有冲突,我就是不知道问题出在哪里 书中定义的第1条规则:如果一个int值的赋值变量是byte、short或char类型,它将自动进行类型转换;e、 g.短s=1234;工作没有问题 书中定义的第2条规则:如果使用算术运算符,编译器首先检查其中一个操作数是否为double类型,如果是这种情况,则另一个操作数自动转换为double类型。对float、long和int重复同样的操作 我的问题在于这样一个案例

我最近通过一本面向编程初学者的书开始学习java。关于类型转换和算术运算符的两条规则似乎在逻辑上有冲突,我就是不知道问题出在哪里

书中定义的第1条规则:如果一个int值的赋值变量是byte、short或char类型,它将自动进行类型转换;e、 g.短s=1234;工作没有问题

书中定义的第2条规则:如果使用算术运算符,编译器首先检查其中一个操作数是否为double类型,如果是这种情况,则另一个操作数自动转换为double类型。对float、long和int重复同样的操作

我的问题在于这样一个案例

short a = 1; 
short b = 2; 
short c = a+b;  
我只是不明白为什么我需要显式地进行类型转换,即
short c=(short)(a+b)
;使此代码正常工作。根据规则2,上述代码应生成一个整数值3,然后根据规则1,该整数值应自动转换为short


如果您对相关的、初学者友好的阅读材料有任何帮助或提示,我们将不胜感激。

这是因为
a
b
不是编译时常量

这称为隐式缩小,仅当编译器可以确定分配给变量的值符合该变量类型的范围时才允许

尝试将变量设置为常量:

final short a = 1;
final short b = 2;
short c = a+b;  // Will now work.

您可能想知道为什么编译器还不知道这些是常量:这就是语言的定义方式。对于被视为编译时常量的变量,它必须(除其他要求外)明确为最终变量。

这是因为
a
b
不是编译时常量

这称为隐式缩小,仅当编译器可以确定分配给变量的值符合该变量类型的范围时才允许

尝试将变量设置为常量:

final short a = 1;
final short b = 2;
short c = a+b;  // Will now work.

您可能想知道为什么编译器还不知道这些是常量:这就是语言的定义方式。对于被视为编译时常量的变量,它必须(除其他要求外)是明确的最终变量。

这是因为
a
b
不是编译时常量:尝试
final short a=1;最终短b=2;短c=a+b
这是因为
a
b
不是编译时常量:try
final short a=1;最终短b=2;短c=a+b所以要澄清:直接分配给变量的数字已经被视为常量,而变量,除非是最终变量,否则不被视为常量,因此编译器不会检出?除了final,还有其他方法把变量变成常量吗?另外,我想一个实体要成为常数,ti必须不可能改变它们,这就是为什么数字和最终的fariable是常数?这更具体一点。语言规范说,其中一个常量表达式是int-literal。如果你刚刚开始,不要太在意这个。隐式变窄并不是很有用(因为它只发生在非常有限的情况下)。我想,一旦我知道了比jsut“hello world”更多的东西,我就会跨越这座桥。非常感谢您有耐心回答这样一个初学者问题,以便澄清:直接分配给变量的数字已经被视为常量,而变量,除非是最终变量,否则不被视为常量,因此编译器不会签出?除了final,还有其他方法把变量变成常量吗?另外,我想一个实体要成为常数,ti必须不可能改变它们,这就是为什么数字和最终的fariable是常数?这更具体一点。语言规范说,其中一个常量表达式是int-literal。如果你刚刚开始,不要太在意这个。隐式变窄并不是很有用(因为它只发生在非常有限的情况下)。我想,一旦我知道了比jsut“hello world”更多的东西,我就会跨越这座桥。非常感谢您有耐心回答这样一个初学者的问题