LoginSignup
5
2

More than 3 years have passed since last update.

switch文でenumって同じ名前の時に名前の衝突はしないの?

Last updated at Posted at 2019-06-08

はじめに

Javaのswitch文ではenumを式にしてした場合、修飾名を付与しないというのがあります。
2つ以上同じ定数があった場合にコンパイルが通ったのが不思議だったので調べてみました。
結果から先にいうと、修飾は不要なので気にせずにそのまま使って大丈夫です。

enumが1つの場合

こういうenumがあるとします。

FoodType.java
public enum FoodType {
    RICE,
    BREAD,
    OTHER,
}
Main.java
import lombok.AllArgsConstructor;

public class Main {
    public static void main(String[] args) {
        Food food = new Food(FoodType.RICE);
        switch (food.foodType){
        case RICE:
            System.out.println("ごはんだよ");
            break;
        case BREAD:
            System.out.println("パンだよ");
            break;

        default:
            System.out.println("その他だよ");
            break;
        }
    }
}

@AllArgsConstructor
class Food {
    FoodType foodType;
}

Mainの方でswitch文でenum(FoodType)を分岐させています。
この場合、caseをFoodType.RICEではなくRICEと書きます。
(なぜRICEでよいのかというのは後述します。)

enumが2つの場合

先ほどのコードにenumを1つ追加してみます。
ごはんの区分をさらに細かく分けたい場合を想定。

RiceType
public enum RiceType {
    RICE,
    FriedRice,
}

Mainも変更。

Main.java
import lombok.AllArgsConstructor;

public class Main {
    public static void main(String[] args) {
        Food food = new Food(FoodType.RICE,RiceType.RICE);
        switch (food.foodType){
            case RICE:
                switch (food.riceType){
                    case RICE:
                        System.out.println("ごはんだよ");
                        break;
                    case FriedRice:
                        System.out.println("チャーハンだよ");
                        break;
                }
                break;
            case BREAD:
                System.out.println("パンだよ");
                break;

            default:
                System.out.println("その他だよ");
                break;
        }
    }
}
@AllArgsConstructor
class Food {
    FoodType foodType;
    RiceType riceType;
}

なぜ名前が衝突しないのか

上記のコードでコンパイルは通ります。
これは正しいコードですが、Mainの以下の箇所でcase RICE:case RICE:が衝突しないでコンパイルが通ることに疑問を持ちました。
また、コードはすべて載せているのでimportは使用されていません。

      switch (food.foodType){
            case RICE:
                switch (food.riceType){
                    case RICE: 

 コンパイル時に修飾してくれている

調べたところ、コンパイル時にクラス名が修飾されるようになっているため、名前は衝突しないようです。
少し古いですが、以下のサイトの「switchの実装」の項にenumの逆コンパイルの結果が紹介されています。
http://www.ne.jp/asahi/hishidama/home/tech/java/enum.html#h2_switch

まとめ

コンパイル時に修飾される仕組みでした。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2