1.如何自定义枚举类。 枚举类:类的对象是有限个的,确定的。
2.使用enum关键字定义枚举类
public class TestSeason1 {
public static void main(String[] args) {
Season1 spring = Season1.SPRING;
System.out.println(spring);
spring.show();
System.out.println(spring.getSeasonName());
System.out.println();
//1.values()
Season1[] seasons = Season1.values();
for(int i = 0;i < seasons.length;i++){
System.out.println(seasons[i]);
}
//2.valueOf(String name):要求传入的形参name是枚举类对象的名字。
//否则,报java.lang.IllegalArgumentException异常
String str = "WINTER";
Season1 sea = Season1.valueOf(str);
System.out.println(sea);
System.out.println();
Thread.State[] states = Thread.State.values();
for(int i = 0;i < states.length;i++){
System.out.println(states[i]);
}
sea.show();
}
}
interface Info{
void show();
}
//枚举类
enum Season1 implements Info{
SPRING("spring", "春暖花开"){
public void show(){
System.out.println("春天在哪里?");
}
},
SUMMER("summer", "夏日炎炎"){
public void show(){
System.out.println("生如夏花");
}
},
AUTUMN("autumn", "秋高气爽"){
public void show(){
System.out.println("秋天是用来分手的季节");
}
},
WINTER("winter", "白雪皑皑"){
public void show(){
System.out.println("冬天里的一把火");
}
};
private final String seasonName;
private final String seasonDesc;
private Season1(String seasonName,String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season [seasonName=" + seasonName + ", seasonDesc="
+ seasonDesc + "]";
}
// public void show(){
// System.out.println("这是一个季节");
// }
}
【来源其他博文:】
枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。
1、常量的使用
在JDK1.5之前,我们定义常量都是:public static fianl….。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
使用:
public class B {
public static void main(String[] args) {
System.out.println( isRed( Color.BLANK ) ) ; //结果: false
System.out.println( isRed( Color.RED ) ) ; //结果: true
}
static boolean isRed( Color color ){
if ( Color.RED.equals( color )) {
return true ;
}
return false ;
}
}
或者 switch 的使用:
public class B {
public static void main(String[] args) {
showColor( Color.RED );
}
static void showColor(Color color){
switch ( color ) {
case BLANK:
System.out.println( color );
break;
case RED :
System.out.println( color );
break;
default:
System.out.println( color );
break;
}
}
}
2、自定义函数
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
private String name ;
private int index ;
private Color( String name , int index ){
this.name = name ;
this.index = index ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
使用:
public class B {
public static void main(String[] args) {
//输出某一枚举的值
System.out.println( Color.RED.getName() );
System.out.println( Color.RED.getIndex() );
//遍历所有的枚举
for( Color color : Color.values()){
System.out.println( color + " name: " + color.getName() + " index: " + color.getIndex() );
}
}
}
结果:
红色
1
RED name: 红色 index: 1
GREEN name: 绿色 index: 2
BLANK name: 白色 index: 3
YELLO name: 黄色 index: 4
===================================
我们现在来深入了解下枚举。
先参考几篇文章:
在①中这样讲到。如下代码:
public class EnumDemo {
public static void main(String[] args){
//直接引用
Day day =Day.MONDAY;
}
}
//定义枚举类型
enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
反编译可以看到,是这样的:
//反编译Day.class
final class Day extends Enum
{
//编译器为我们添加的静态的values()方法
public static Day[] values()
{
return (Day[])$VALUES.clone();
}
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static Day valueOf(String s)
{
return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);
}
//私有构造函数
private Day(String s, int i)
{
super(s, i);
}
//前面定义的7种枚举实例
public static final Day MONDAY;
public static final Day TUESDAY;
public static final Day WEDNESDAY;
public static final Day THURSDAY;
public static final Day FRIDAY;
public static final Day SATURDAY;
public static final Day SUNDAY;
private static final Day $VALUES[];
static
{
//实例化枚举实例
MONDAY = new Day("MONDAY", 0);
TUESDAY = new Day("TUESDAY", 1);
WEDNESDAY = new Day("WEDNESDAY", 2);
THURSDAY = new Day("THURSDAY", 3);
FRIDAY = new Day("FRIDAY", 4);
SATURDAY = new Day("SATURDAY", 5);
SUNDAY = new Day("SUNDAY", 6);
$VALUES = (new Day[] {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
});
}
}
从反编译的代码可以看出编译器确实帮助我们生成了一个Day类(注意该类是final类型的,将无法被继承)而且该类继承自
java.lang.Enum
类,该类是一个抽象类(稍后我们会分析该类中的主要方法),除此之外,编译器还帮助我们生成了7个Day类型的实例对象分别对应枚举中定义的7个日期,这也充分说明了我们前面使用关键字enum定义的Day类型中的每种日期枚举常量也是实实在在的Day实例对象,只不过代表的内容不一样而已。
现在能明白:使用关键字enum定义的枚举类型,在编译期后,将转换成为一个实实在在的类,而在该类中,会存在每个在枚举类型中定义好变量的对应实例对象,如上述的MONDAY枚举类型对应public static final Day MONDAY;
,同时编译器会为该类创建两个方法,分别是values()和valueOf()。
所以最前面的关于季节的代码:
public class Season1Demo{
public static void main(String[] args) {
Season spring = Season.WINTER;
spring.show();
Season.SPRING.show();
Season.AUTUMN.show();
}
}
interface Info {
void show();
}
// 枚举类
enum Season implements Info {
SPRING("spring", "春暖花开") {
// public void show() {
// System.out.println("春天在哪里?");
// }
},
SUMMER("summer", "夏日炎炎") {
//该实例重写了 show 方法
public void show() {
System.out.println("生如夏花");
}
},
AUTUMN("autumn", "秋高气爽") {
public void show() {
System.out.println("秋天是用来分手的季节");
}
},
WINTER("winter", "白雪皑皑") {
public void show() {
System.out.println("冬天里的一把火");
}
};
private final String seasonName;
private final String seasonDesc;
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]";
}
public void show(){
System.out.println("这是一个季节");
}
}
结果:
冬天里的一把火
这是一个季节
秋天是用来分手的季节
我个人小结:枚举Season最后转换成了Season类(继承了Enum类),然后在该类中定义好了类型为Season的成员变量SPRING
、SUMMER
、AUTUMN
、WINTER
并实例化。
在引用另外看到的篇文章写道的:
enum这个关键字,可以理解为跟class差不多,这也个单独的类。可以看到,上面的例子里面有属性,有构造方法,有getter,也可以有setter,但是一般都是构造传参数。还有其他自定义方法。那么在这些东西前面的,以逗号隔开的,最后以分号结尾的,这部分叫做,这个枚举的实例。也可以理解为,class new 出来的实例对象。这下就好理解了。只是,class,new对象,可以自己随便new,想几个就几个,而这个enum关键字,他就不行,他的实例对象,只能在这个enum里面体现。也就是说,他对应的实例是有限的。这也就是枚举的好处了,限制了某些东西的范围,举个栗子:一年四季,只能有春夏秋冬,你要是字符串表示的话,那就海了去了,但是,要用枚举类型的话,你在enum的大括号里面把所有的选项,全列出来,那么这个季节的属性,对应的值,只能在里面挑。不能有其他的。
所以:
SPRING("spring", "春暖花开") {
public void show() {
System.out.println("春天在哪里?");
}
},
该代码相当就是new出了Season对象并实例化,该如果这里没写show()方法则调用的Season实现的show()方法,但这里重新定义了,相当于覆盖了show()方法。
再看一个例子(包含抽象方法的枚举类):
定义一个 Operation 枚举类,有4个枚举值PLUS、MINUS、TIMES、DIVIDE,分别代表加、减、乘、除,该枚举类有一个 calculate() 方法,用于完成计算。
public enum Operation {
// 用于执行加法运算
PLUS { // 花括号部分其实是一个匿名内部子类
@Override
public double calculate(double x, double y) {
return x + y;
}
},
// 用于执行减法运算
MINUS { // 花括号部分其实是一个匿名内部子类
@Override
public double calculate(double x, double y) {
// TODO Auto-generated method stub
return x - y;
}
},
// 用于执行乘法运算
TIMES { // 花括号部分其实是一个匿名内部子类
@Override
public double calculate(double x, double y) {
return x * y;
}
},
// 用于执行除法运算
DIVIDE { // 花括号部分其实是一个匿名内部子类
@Override
public double calculate(double x, double y) {
return x / y;
}
};
//为该枚举类定义一个抽象方法,枚举类中所有的枚举值都必须实现这个方法
public abstract double calculate(double x, double y);
}
从上可以看出,掌握、理解枚举,重要要知道枚举、和枚举变量的实质是什么。
枚举最后转换就是一个特殊的类,其中的枚举变量就是实例化对象。可以就这么看:
public class HelloDemo2 {
public static void main(String[] args) {
Season1 SPRING = new Season1("spring", "春暖花开") {
public void show() {
System.out.println("春天在哪里?");
};
};
SPRING.show();
}
}
interface Info1{
void show();
}
class Season1 implements Info1{
private String seasonName;
private String seasonDesc;
public Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
@Override
public void show() {
System.out.println("这是一个季节");
}
}
1.JDK提供的常用的三个注解
@Override: 限定重写父类方法, 该注释只能用于方法
@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
@SuppressWarnings: 抑制编译器警告
2.如何自定义注解
以SuppressWarnings为例进行创建即可
Retention: SOURCE CLASS RUNTIME
Target:
Documented:javadoc
Inherited