考虑:
class UnderstandingConversion {
public static void main(String[] args) {
int a=10, b=20;
byte c = (a>b) ? 40 : 50;
System.out.println(c);
// output : lossy conversion error
}
}
这段代码给出了一个错误,我理解为“有损转换”,但如果我在代码中使用Final
关键字,如下所示,它工作正常。
class UnderstandingConversion {
public static void main(String[] args) {
final int a=10, b=20;
byte c = (a>b)? 40 : 50;
System.out.println(c);
// Output: 50
}
}
final
在这里是如何工作的,降级是如何发生的?
编译器100%确信
要证明编译器只考虑else
值,可以这样做:
final int a=10, b=20;
byte c = (a>b) ? 1234 : 50;
它会编译得很好,但是
final int a=10, b=20;
byte c = (a>b) ? 50 : 1234;
将产生一个错误。1234超出了字节的范围,但是在第一个例子中它是非常好的,因为这个分支被忽略了。
我相信具有更好专业知识的人可以指出JLS段落来解释这里正在发生的事情。
观察结果更新
事实证明,如果我们检查字节码,我们很可能会看到a
和b
被替换为常量值(也许根本没有分支)。我已经调试了该代码,并在三元运算符(使用调试器)之前将A值更改为10000,但执行仍然产生c = 50,尽管A
这是一个有趣的事实;)谢谢你提出一个问题,这样我就可以学习新东西
JLS具有预定义的分配转换规则。
如果表达式是字节、短、字符或整型的常量表达式 (§15.28):
如果变量的类型是byte、short或char,并且常量表达式的值可以在变量的类型中表示,则可以使用收缩原语转换。
常量表达式的定义:
§4.12.4定义了最终变量是什么
一个原始类型或类型字符串的变量,是最终的,并用编译时常量表达式(15.28)初始化,称为常量变量。
问题内容: 关键字如何使变量不可变?维基百科说没有。 问题答案: 在Java中,术语 final 是指引用,而不 可变 是指对象。将修饰符分配给引用意味着它不能更改为指向另一个对象,但是如果对象是可变的,则可以对其进行修改。 例如: 就像Wikipedia文章中提到的那样,如果您来自C ++,则必须分离出into 和不可变的概念。
问题内容: 我正在尝试实现在robotframework中使用Java方法。我遵循了本教程:https : //blog.codecentric.de/en/2016/01/robot-framework-tutorial-2016-remote-server- keywords-in-java/ 使用的类如下:https : //github.com/robotframework/jrobotr
问题内容: 我读过“ 何时在Java中使用’volatile’? ”,但我仍然感到困惑。我怎么知道何时应该将变量标记为volatile?如果我弄错了,或者在需要的东西上省略了挥发物,或者在不需要的东西上放置了挥发物,该怎么办?确定多线程代码中哪些变量应该是易变的,有什么经验法则? 问题答案: 当你想让一个多线程访问一个成员变量但不需要复合原子性(不确定这是否是正确的术语)时,基本上就可以使用它。
问题内容: 当ai遇到关键字时,我正在研究Java中的方法重写。在Internet和其他来源上进行了大量搜索之后,我得出结论,当实例变量的名称与构造函数的参数相同时,将使用关键字。我是对还是错? 问题答案: 是实例中当前实例的别名或名称。它对于消除实例变量与局部变量(包括参数)的区别很有用,但它本身可以用来简单地引用成员变量和方法,调用其他构造函数重载或简单地引用 实例 。适用用途的一些示例(并非
问题内容: 我试图了解java关键字的this实际作用。我一直在阅读Sun的文档,但对于this实际操作仍然不甚了解。 java 关键字 问题答案: 关键字是对当前对象的引用。 另一种思考方式是关键字就像你用来引用自己的人称代词。对于相同的概念,其他语言使用不同的词。VB使用Me和Python约定(因为Python不使用关键字,只是每个方法的隐式参数)将被使用。 如果要引用本质上属于你的对象,你将
问题内容: 我已经读过“ raise”的正式定义,但是我仍然不太明白它的作用。 简单来说,什么是“筹款”? 示例用法将有所帮助。 问题答案: 它有2个目的。 [yentup给出了第一个。 它用于引发错误。 它用于引发您自己的错误。 第二个方法是在异常处理程序中重新引发 当前 异常,以便可以在调用堆栈中进一步处理该异常。