在Java中打开非Ints

时间:2011-12-30 21:02:01

标签: java

我无法弄清楚Java中交换机的内部工作原理 我被告知,对于所有原语,值被提升为整数。

但是,在下面的例子中,我正在测试一个字节变量,任何大于127的情况都不会编译:

byte k = 5;
switch(k){
  case 128:    //fails to compile, possible loss of precision  

我意识到这是一个错误,并没有问题。我的问题是:
如果JVM采用“k”的值并在测试每个案例之前将其提升为整数,那么JVM如何跟踪它是否正在切换一个字节?

6 个答案:

答案 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)将解决问题。