当前位置: 移动技术网 > IT编程>开发语言>Java > 三分钟快速掌握Java中枚举(enum)

三分钟快速掌握Java中枚举(enum)

2019年07月22日  | 移动技术网IT编程  | 我要评论
什么是枚举? 枚举是jdk5引入的新特性。在某些情况下,一个类的对象是固定的,就可以定义为枚举。在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全。枚举有以下

什么是枚举?

枚举是jdk5引入的新特性。在某些情况下,一个类的对象是固定的,就可以定义为枚举。在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全。枚举有以下特点:

  1. java中枚举和类、接口的级别相同。
  2. 枚举和类一样,都有自己的属性、方法、构造方法,不同点是:枚举的构造方法只能是private修饰,也就无法从外部构造对象。构造方法只在构造枚举值时调用。
  3. 使用enum关键字声明一个枚举类型时,就默认继承自java中的 java.lang.enum类,并实现了java.lang.seriablizablejava.lang.comparable两个接口。
  4. 所有的枚举值都是 public static final 的,且非抽象的枚举类不能再派生子类。
  5. 枚举类的所有实例(枚举值)必须在枚举类的第一行显式地列出,否则这个枚举类将永远不能产生实例。
  6. 判断枚举是否相同时,使用 == 和 equals 是一样的。

下面是 java.lang.enum类中的 equals()

// 这里是final修饰的,不允许子类重写 
public final boolean equals(object other) { 
 return this==other;
}

枚举的常用方法

int compareto(e o)

比较此枚举与指定对象的顺序。在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。 枚举常量只能与相同枚举类型的其他枚举常量进行比较。

// enum 中的源码
public final int compareto(e o) {
 enum other = (enum)o;
 enum self = this;
 if (self.getclass() != other.getclass() && // optimization
  self.getdeclaringclass() != other.getdeclaringclass())
  throw new classcastexception();
 return self.ordinal - other.ordinal;
}

string name()

返回此枚举实例的名称。

static values()

返回一个包含全部枚举值的数组,可以用来遍历所有枚举值。

string tostring()

返回此枚举实例的名称,即枚举值。与 name() 一样。

// enum 中 name() 和 tostring()
public string tostring() {
 return name;
}
public final string name() {
 return name;
}

int ordinal()

返回枚举值在枚举类中的索引值(从0开始),即枚举值在枚举声明中的顺序,这个顺序根据枚举值声明的顺序而定。

<t extends enum<t>> valueof()

返回带指定名称的指定枚举类型的枚举常量,名称必须与在此类型中声明枚举常量所用的标识符完全匹配(不允许使用额外的空白字符)。这个方法与tostring相对应,因此重写 tostring() 方法,一定要重写 valueof()方法(我们可以重写 tostring() 方法,但不能自己重写 valueof() 方法,当我们重写 tostring()方法时,valueof() 方法会自动重写,不用我们理会。)

枚举的应用

枚举是一种特殊的类型,其用法和普通的类使用非常相似。

代替一组常量

public enum color { 
 red, green, blank, yellow 
}

switch 语句中使用

// jdk1.6 中switch加入了对枚举的支持
enum signal { 
 green, yellow, red 
} 

...
switch (color) { 
 case red: 
  color = signal.green; 
  break; 
}
...

向枚举中添加方法

public enum color { 

 red("红色"), green("绿色"), blank("白色"), yello("黄色"); 

 // 成员变量 
 private string name; 
 // 构造方法 
 private color(string name) { 
  this.name = name; 
 } 

 // get set 方法 
 public string getname() { 
  return name; 
 } 
 public void setname(string name) { 
  this.name = name; 
 } 

}

实现接口

public interface behaviour { 
 void print(); 
} 

public enum color implements behaviour{ 
 red("红色", 1), green("绿色", 2), blank("白色", 3), yello("黄色", 4); 

 //接口方法 
 @override 
 public void print() { 
  system.out.println(this.index+":"+this.name); 
 } 
}

包含抽象方法的枚举类

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);

}

使用枚举实现单例(单例的最佳实践)

好处:

     1.利用的枚举的特性实现单例

     2.由jvm保证线程安全

     3.序列化和反射攻击已经被枚举解决

public enum singleton {
 instance;
 public singleton getinstance(){
  // 增加这个方法是让别人明白怎么使用,因为这种实现方式还比较少见。
  return instance;
 }
}

其他关于枚举的使用

enumset

range(e from, e to)

从枚举值中获取一段范围的 set。

for(weekdayenum day : enumset.range(weekdayenum.mon, weekdayenum.fri)) { 
  system.out.println(day); 
}

of(e first, e... rest)

创建一个最初包含指定元素的枚举 set。

noneof(class<e> elementtype)

创建一个具有指定元素类型的空枚举 set。

enummap

enummap(class<k> keytype)

创建一个具有指定键类型的空枚举map。

map<weather, string> enummap = new enummap<weather, string>(weather.class);
enummap.put(weather.sunny, "晴天");
enummap.put(weather.rainy, "雨天");

android中的枚举

enum 需要占用较大的内存,如果对内存敏感,请尽量少使用 enum,换成静态常量。

但是如果不使用枚举,会出现一些安全隐患,所以官方推出了两个注解,可以在编译时期进行类型检查,以此替代枚举。这两个注解分别是:@intdef 和 @stringdef。位于compile 'com.android.support:support-annotations:+' 。

使用示例

@stringdef的使用与 @intdef一致,这里以 @intdef为例。

public interface qrcodetype {

 int wechat = 0;
 int alipay = 1;

 @intdef({wechat , alipay })
 @retention(retentionpolicy.source)
 @target({elementtype.field, elementtype.method, elementtype.parameter})
 @interface checker {

 }

}

public class qrcode {

 @qrcodetype.checker // 定义在属性
 private int type;

 public void settype(@qrcodetype.checker int type) { // 定义在参数
  this.type= type;
 }

  @qrcodetype.checker // 定义在方法(也就是检查返回值的类型)
 public int gettype() {
  return type;
 }

}

使用建议

开发中使用范围最广的就是利用枚举代替一组静态常量,这种情况可以使用以上注解方式替代。
当枚举还含有其它功能时(如:包含其它定义的方法),则不能替换。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网