理由はかなり複雑ですが、すべてJava言語仕様の詳細(必要に応じて詳細に印刷)にあります。
まず、JLS 14.11はswitch
ステートメントについて次のように述べています。
「switchステートメントに関連付けられているすべてのcase定数は、switchステートメントの式のタイプと互換性のある代入でなければなりません(§5.2)。」
これは、とに それぞれ'a'
割り当て可能である必要があることを意味します。Integer
Byte
しかし、それは正しく聞こえません:
実際、どちらも正しくありません。理由を理解するには、割り当てコンテキストで許可されている内容について、実際にJLS 5.2を読む必要があります。
「割り当てコンテキストでは、次のいずれかを使用できます。
- アイデンティティ変換(§5.1.1)
- 拡大プリミティブ変換(§5.1.2)
- 拡大する参照変換(§5.1.5)
- 拡張参照変換とそれに続くボックス化解除変換
- 拡張参照変換とそれに続くボックス化解除変換、その後の拡張プリミティブ変換
- ボクシング変換(§5.1.7)
- ボクシング変換とそれに続く拡大参照変換
- ボックス化解除変換(§5.1.8)
- ボックス化解除変換とそれに続くプリミティブ変換の拡大。」
行くために'a'
するInteger
ために、我々は、必要があるだろう1は広げるchar
の値をint
、ボックスint
にInteger
。ただし、許可されている変換の組み合わせを見ると、拡大プリミティブ変換の後にボックス化変換を行うことはできません。
したがって'a'
、Integer
許可されていません。これは、最初のケースのコンパイルエラーを説明します。
'a'
to Byte
は原始的なナローイング変換を伴うため、許可されていないと思われるかもしれません...これはリストにはまったくありません。実際、リテラルは特殊なケースです。 JLS 5.2ではさらに次のように述べています。
「さらに、式がバイト、ショート、char、またはint型の定数式(§15.28)の場合:
これらの第二は、に適用される'a'
とByte
、理由は次のとおりです。
- 文字リテラルは定数式であり、
- の値
'a'
は97
10進数で、byte
(-128
〜+127
)の範囲内です。
これは、2番目の例にコンパイルエラーがない理由を説明しています。
1- はJavaののサブタイプではないため'a'
、aにボックス化してCharacter
から拡大Character
するInteger
ことCharacter
はできませんInteger
。ソースタイプがターゲットタイプのサブタイプである場合にのみ、拡大参照変換を使用できます。