我无法弄清楚Java中交换机的内部工作原理 我被告知,对于所有原语,值被提升为整数。
但是,在下面的例子中,我正在测试一个字节变量,任何大于127的情况都不会编译:
byte k = 5;
switch(k){
case 128: //fails to compile, possible loss of precision
我意识到这是一个错误,并没有问题。我的问题是:
如果JVM采用“k”的值并在测试每个案例之前将其提升为整数,那么JVM如何跟踪它是否正在切换一个字节?
答案 0 :(得分:9)
switch
声明不仅限于int
。 Java语言规范(JLS),section 14.11, The switch Statement,陈述
Expression的类型必须是char,byte,short,int,Character, 发生字节,短整数或整数类型,或发生编译时错误。
因此,您的byte
不会升级为int
。 JLS继续说你正在做的事情会导致编译时错误:
与switch语句关联的每个case常量表达式都必须 可分配给开关表达式的类型。
...因为128不能分配给byte
。
答案 1 :(得分:3)
问题是它没有提升k的值,它试图采用case语句(128 - 有符号整数)并将其分配给一个字节。当128大于1字节(7位+符号位)时,编译失败。
例如
byte k = 128;
也无法编译。 请参阅Java Language Specification
答案 2 :(得分:2)
它没有编译,因为:
类型不匹配:无法从int转换为字节
这是显而易见的,因为你的k是byte
类型,而文字128是根据Java规则的int。
如果您将案例陈述更改为:
case (byte) 128:
然后编译没有任何错误。
答案 3 :(得分:1)
你只需要转换为byte
:
switch(k) {
case (byte) 128:
}
没关系 - 问题只是没有从文字128到byte
的隐式转换。简单分配会遇到同样的问题:
// Invalid
byte a = 128;
// Valid
byte b = (byte) 128;
b
的值实际为-128,因为128超出了Java byte
的范围 - 但位模式是正确的,所以在很多情况下这就是你想要的;它也是在switch语句中给出上述情况的值。
答案 4 :(得分:1)
Java规范说:
与switch语句关联的每个case常量表达式必须可分配(第5.2节)到switch表达式的类型。
JVM Spec表示该类型已被提升,但这是一个不同的(非编译时)问题。
答案 5 :(得分:0)
字节的大小仅为-128到127。当你将byte作为switch case传递时,它是精确丢失并突出显示编译时所需的字节,发现int错误。 byte(128)将解决问题。