2011-12-30 46 views
4

我无法找出Java中交换机的内部工作原理 我被告知,对于所有原语,该值都被提升为整数。在Java中切换非Ints

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

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

我意识到这是一个错误,没有任何问题,这一点。我的问题是:
JVM如何跟踪它在一个字节上的切换,如果它在测试每个个案之前将值“k”提升为一个整数?

+0

我不关心编译错误,这只是一个例子。开关变量是否被提升为整数? – Adam 2011-12-30 21:17:07

+0

它被提升,请参阅我的答案或JVM规范第7.10节 – 2011-12-30 21:34:41

回答

3

问题是它没有提升k的值,它试图将case语句(128 - 有符号整数)并将其分配给一个字节。由于128大于1个字节(7位+符号位),编译失败。

例如

byte k = 128; 

也将编译失败。 见Java Language Specification

+0

我意识到那一部分。我的问题是,如果被切换的值被提升为一个整数,那么JVM如何跟踪真正的类型是什么类型 – Adam 2011-12-30 21:25:18

+0

正在切换的值(例如k)不会被提升为整数,而是会尝试使用大小写常量被解释为要切换的值的类型(例如字节)。 (这是有道理的吗?) – Charlie 2011-12-30 21:28:39

+0

你是说,如果不知何故值变成了一个整数?哪些不会发生,因为你已经将它定义为一个字节? – Charlie 2011-12-30 21:32:30

2

它不编译因为:

类型不匹配:不能从int转换为字节

这是显而易见的,因为你的k为byte类型和文字128是一个int按照Java规则。

如果更改case语句:

case (byte) 128: 

那么它将编译没有任何错误。

0

字节的大小只有-128到127。当你传递字节作为开关的情况下,它是精度丢失并突出显示编译时间所需的字节,发现int错误。字节(128)将解决问题。

+1

字节是-128到127 – Charlie 2011-12-30 21:11:38

+0

无论如何这是错误的答案......'字节'不被提升。 – Paul 2011-12-30 21:12:30

+0

@Charlie,更新了我的答案。谢谢 – kosa 2011-12-30 21:13:27

1

你只需要转换为byte

switch(k) { 
    case (byte) 128: 
} 

这很好 - 问题只是,有没有从字面128 byte的隐式转换。你用简单的分配同样的问题:

// Invalid 
byte a = 128; 

// Valid 
byte b = (byte) 128; 

b值将实际上是-128,因为128是一个Java byte的范围之外 - 而比特模式是正确的,所以在很多情况下,这是你想要的;这也是在switch语句中碰到上述情况的价值。

1

Java规范说:

Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.

JVM规范,说的类型会提升,但是这是一个不同的(不编译时间)的问题。

9

switch声明不限于int。Java语言规范(JLS),section 14.11, The switch Statement,指出

The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type, or a compile-time error occurs.

byte,因此,不提升到int。在JLS接着说,你在做什么会导致编译时错误:

Every case constant expression associated with a switch statement must be assignable to the type of the switch Expression.

...因为128不是分配给一个byte