Enum翻译

2017-08-03  本文已影响0人  简书ZJM

当我们想要一个变量从一些预先定义常量得到,我们可以这么做,我们可以从这些常量声明常量和设置x,请设想x是当前日期(星期几)和这可以有任何值从周日到周五,我们可以在java使用整形常量来码代码

public class Main {
 
    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;
 
    private int currentDay = SUNDAY;
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main obj = new Main();
        obj.setCurrentDay(WEDNESDAY);
 
        int today = obj.getCurrentDay();
 
        switch (today) {
        case SUNDAY:
            System.out.println("Today is SUNDAY");
            break;
        case MONDAY:
            System.out.println("Today is MONDAY");
            break;
        case TUESDAY:
            System.out.println("Today is TUESDAY");
            break;
        case WEDNESDAY:
            System.out.println("Today is WEDNESDAY");
            break;
        case THURSDAY:
            System.out.println("Today is THURSDAY");
            break;
        case FRIDAY:
            System.out.println("Today is FRIDAY");
            break;
        case SATURDAY:
            System.out.println("Today is SATURDAY");
            break;
 
        default:
            break;
        }
    }
 
    public void setCurrentDay(int currentDay) {
        this.currentDay = currentDay;
    }
 
    public int getCurrentDay() {
        return currentDay;
    }
 
}

这段代码的问题是我们设置任意的值作为现在日期

obj.setCurrentDay(100);

和编译将不会给我任何错误,接着在switch/case 我们将会错过这个值,所以java给我们一个解决方案这就是Enumeration or Enum(枚举),如果我们使用Enum枚举来重写这段代码

public class Main {
 
    public enum WeekDays {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
    }
 
    private WeekDays currentDay = WeekDays.SUNDAY;
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main obj = new Main();
        obj.setCurrentDay(WeekDays.WEDNESDAY);
 
        WeekDays today = obj.getCurrentDay();
 
        switch (today) {
        case SUNDAY:
            System.out.println("Today is SUNDAY");
            break;
        case MONDAY:
            System.out.println("Today is MONDAY");
            break;
        case TUESDAY:
            System.out.println("Today is TUESDAY");
            break;
        case WEDNESDAY:
            System.out.println("Today is WEDNESDAY");
            break;
        case THURSDAY:
            System.out.println("Today is THURSDAY");
            break;
        case FRIDAY:
            System.out.println("Today is FRIDAY");
            break;
        case SATURDAY:
            System.out.println("Today is SATURDAY");
            break;
 
        default:
            break;
        }
    }
 
    public void setCurrentDay(WeekDays currentDay) {
        this.currentDay = currentDay;
    }
 
    public WeekDays getCurrentDay() {
        return currentDay;
    }
 
}

现在我们有了一个安全的类型,我不可以随意设置除了星期数作为当前日期的量,这是一个巨大的改善,和我们应该使用他,但在Android这有一个问题
Android in Enum:枚举在java中是一个完整的类,在枚举的类中枚举中每个量都是一个object,所以我们使用越早Enum量将会消耗更多的内存,甚至在较低版本的安卓设备(<=2.2),这将会因为Enum有很多的性能问题在JIT编译器中被解决,现在我们可以使用Enum在安卓应用,但如果我们的应用是一个内存巨大的应用或者是个游戏应用,我们最好使用整形变量替代Enum,但这个问题依旧存在。
这有一个解决方法,Android支持注解库有一些很好的注解类这可以用来尽早的发现bug(在编译期间),intDef和stringDef是两个魔法变量注解这可以用来替代Enum,这将会帮助在编译期间我们去检查像Enum这样的变量,下面的代码展示了如何去使用IntDef去替代Enum

public class MainActivity extends Activity {
 
    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;
 
    @IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface WeekDays {}
 
    @WeekDays int currentDay = SUNDAY;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setCurrentDay(WEDNESDAY);
 
        @WeekDays int today = getCurrentDay();
 
        switch (today){
            case SUNDAY:
                break;
            case MONDAY:
                break;
            case TUESDAY:
                break;
            case WEDNESDAY:
                break;
            case THURSDAY:
                break;
            case FRIDAY:
                break;
            case SATURDAY:
                break;
            default:
                break;
        }
 
    }
 
    public void setCurrentDay(@WeekDays int currentDay) {
        this.currentDay = currentDay;
    }
 
    @WeekDays
    public int getCurrentDay() {
        return currentDay;
    }
}

现在我们不可以设置任何的量除了星期数的值作为当前日期或者今天的量,编译将会检查这个和报错,如果我们使用AndroidStdio IDE将会给一个建议关于该值,那么怎么去使用它呢,在一开始就声明它为常量

public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;

接着在@IntDef中声明这些常量

@IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
@Retention(RetentionPolicy.SOURCE)
public @interface WeekDays {}

去设置一个量作为星期类型,所以除了星期数将没有值可以去设置这个值,我们可以像下面那样去声明它

@WeekDays int currentDay ;

现在如果有任何设置任何除了星期数的值,编译器将会给出一个错误,去设置参数的功能和返回星期数类型的功能

public void setCurrentDay(@WeekDays int currentDay) {
    this.currentDay = currentDay;
}
 
@WeekDays
public int getCurrentDay() {
    return currentDay;
}

@StringDef 使用方法相同

public class MainActivity extends Activity {
 
    public static final String SUNDAY = "sunday";
    public static final String MONDAY = "monday";
    public static final String TUESDAY = "tuesday";
    public static final String WEDNESDAY = "wednesday";
    public static final String THURSDAY = "thursday";
    public static final String FRIDAY = "friday";
    public static final String SATURDAY = "saturday";
 
 
    @StringDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface WeekDays {}
 
 
    @WeekDays String currentDay = SUNDAY;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setCurrentDay(WEDNESDAY);
 
        @WeekDays String today = getCurrentDay();
 
 
        switch (today){
            case SUNDAY:
                break;
            case MONDAY:
                break;
            case TUESDAY:
                break;
            case WEDNESDAY:
                break;
            case THURSDAY:
                break;
            case FRIDAY:
                break;
            case SATURDAY:
                break;
            default:
                break;
        }
 
    }
 
    public void setCurrentDay(@WeekDays String currentDay) {
        this.currentDay = currentDay;
    }
 
    @WeekDays
    public String getCurrentDay() {
        return currentDay;
    }
}

为了使用这个特点,你必须加上支持注解的库在你的项目中,如果你使用Android Stdio,你可以在Gradle加上以下的依赖。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    ...
    compile 'com.android.support:support-annotations:22.0.0'
}

以上为翻译以下地址文章

https://noobcoderblog.wordpress.com/2015/04/12/java-enum-and-android-intdefstringdef-annotation/

上一篇下一篇

猜你喜欢

热点阅读