public class Ambiguity {
public static void main(String[] args) {
int Integer = 3;
System.out.println((Integer) null); // cast; prints "null"
System.out.println((Integer) - Integer); // subtraction; prints "0"
System.out.println((Integer) (-Integer)); // cast; prints "-3"
}
}
在Java中,我可以声明一个名为Integer的变量,然后编写可以转换为Integer类或包含Integer变量的表达式的代码。Java如何解决类名和变量名之间的歧义?规格书中是否有正式的规则?这是一种特别的启发式吗?我知道C编译器必须处理类似的问题,并且我知道它们是如何处理的,但是Java似乎更宽容。
请参考JLS的评估顺序
"Java编程语言保证操作符的操作数似乎按照特定的求值顺序求值,即从左到右。"
(Integer) -Integer
现在,当解析它时,很明显存在一个以(Integer)
和Integer
为操作数的减法运算符。从左边开始,括号表达式应该被计算为一个值(因为它后面跟着和操作符),因此它不会假设它是Type,而是变量。
(Integer) (-Integer)
当解析时,有两个标记(每个都在括号内)没有任何操作符,因此没有歧义(表达式是值还是类型)。第一个括号始终是Type,后面跟着的表达式将始终被求值为要强制转换的值。
据我所知,解析器是从右到左的。第一个说法是显而易见的。
在第二个语句中,解析器首先找到一个变量,然后在他期望另一个变量的符号之后找到一个表达式"-",但是他找到了一个右括号,这意味着他首先需要解析括号内的表达式。在你的例子中只有一个变量。因此,解析器获取该值并将其与另一个变量相减。
在第三个语句中,解析器首先找到右括号=>,然后解析括号内的表达式(-3),之后他没有找到任何操作(+,*,/,-例如),所以下一个括号表示这是一个强制转换。
没有歧义,编译器总是期望class或变量,没有两者都适合的操作。例如
Integer Integer = 1;
Integer = new Integer(1);
Integer = Integer + 1;
1)在赋值中总是存在类型/变量名称对
2)只能在类
上调用new算术运算中的3不能是任何类名