当前位置:  编程技术>java/j2ee

java中的枚举类型详细介绍

    来源: 互联网  发布时间:2014-10-21

    本文导语:  枚举中有values方法用于按照枚举定义的顺序生成一个数组,可以用来历遍。我们自定义的枚举类都是继承自java.lang.Enum,拥有一下实例中的功能: 代码如下: //: enumerated/EnumClass.java // Capabilities of the Enum class import static net.mindview...

枚举中有values方法用于按照枚举定义的顺序生成一个数组,可以用来历遍。我们自定义的枚举类都是继承自java.lang.Enum,拥有一下实例中的功能:
代码如下:

//: enumerated/EnumClass.java
// Capabilities of the Enum class
import static net.mindview.util.Print.*;
enum Shrubbery { GROUND, CRAWLING, HANGING }
public class EnumClass {
  public static void main(String[] args) {
    for(Shrubbery s : Shrubbery.values()) {
      print(s + " ordinal: " + s.ordinal());
      printnb(s.compareTo(Shrubbery.CRAWLING) + " ");
      printnb(s.equals(Shrubbery.CRAWLING) + " ");
      print(s == Shrubbery.CRAWLING);
      print(s.getDeclaringClass());
      print(s.name());
      print("----------------------");
    }
    // Produce an enum value from a string name:
    for(String s : "HANGING CRAWLING GROUND".split(" ")) {
      Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
      print(shrub);
    }
  }
} /* Output:
GROUND ordinal: 0
-1 false false
class Shrubbery
Joshua Bloch was extremely helpful in developing this chapter.
GROUND
----------------------
CRAWLING ordinal: 1
true true
class Shrubbery
CRAWLING
----------------------
HANGING ordinal: 2
false false
class Shrubbery
HANGING
----------------------
HANGING
CRAWLING
GROUND
*///:~

我们还可以使用静态的枚举引用:
代码如下:

//: enumerated/Spiciness.java
package enumerated;
public enum Spiciness {NOT, MILD, MEDIUM, HOT, FLAMING} ///:~
//: enumerated/Burrito.java
package enumerated;
import static enumerated.Spiciness.*;
public class Burrito {
  Spiciness degree;
  public Burrito(Spiciness degree) { this.degree = degree;}
  public String toString() { return "Burrito is "+ degree;}
  public static void main(String[] args) {
    System.out.println(new Burrito(NOT));
    System.out.println(new Burrito(MEDIUM));
    System.out.println(new Burrito(HOT));
  }
} /* Output:
Burrito is NOT
Burrito is MEDIUM
Burrito is HOT
*///:~

向枚举添加方法
除了不能被继承之外,枚举可以当作一般的类来看待,这意味着可以向枚举添加方法,还可以在枚举中定义main方法:
代码如下:

//: enumerated/OzWitch.java
// The witches in the land of Oz.
import static net.mindview.util.Print.*;
public enum OzWitch {
  // Instances must be defined first, before methods:
  WEST("Miss Gulch, aka the Wicked Witch of the West"),NORTH("Glinda, the Good Witch of the North"),EAST("Wicked Witch of the East, wearer of the Ruby " + "Slippers, crushed by Dorothy's house"),SOUTH("Good by inference, but missing");
  private String description;
  // Constructor must be package or private access:
  private OzWitch(String description) {
    this.description = description;
  }
  public String getDescription() { return description; }
  public static void main(String[] args) {
    for(OzWitch witch : OzWitch.values())
      print(witch + ": " + witch.getDescription());
  }
} /* Output:
WEST: Miss Gulch, aka the Wicked Witch of the West
NORTH: Glinda, the Good Witch of the North
EAST: Wicked Witch of the East, wearer of the Ruby Slippers, crushed by Dorothy's house
SOUTH: Good by inference, but missing
*///:~

代码如下:

//: enumerated/SpaceShip.java
public enum SpaceShip {
  SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;
  public String toString() {
    String id = name();
    String lower = id.substring(1).toLowerCase();
    return id.charAt(0) + lower;
  }
  public static void main(String[] args) {
    for(SpaceShip s : values()) {
      System.out.println(s);
    }
  }
} /* Output:
Scout
Cargo
Transport
Cruiser
Battleship
Mothership
*///:~

switch语句中的枚举
  枚举的一种重要作用就是在switch语句中,通常switch语句仅对整型值起作用,但是枚举中有内置的整型顺序,因此实例的顺序可以通过某种方法获得,因此enums就可以在switch语句中使用:
代码如下:

//: enumerated/TrafficLight.java
// Enums in switch statements.
import static net.mindview.util.Print.*;
// Define an enum type:
enum Signal { GREEN, YELLOW, RED, }
  public class TrafficLight {
    Signal color = Signal.RED;
    public void change() {
    switch(color) {
      // Note that you don't have to say Signal.RED
      // in the case statement:
      case RED: color = Signal.GREEN;
            break;
      case GREEN: color = Signal.YELLOW;
            break;
      case YELLOW: color = Signal.RED;
            break;
    }
  }
  public String toString() {
    return "The traffic light is " + color;
  }
  public static void main(String[] args) {
    TrafficLight t = new TrafficLight();
    for(int i = 0; i < 7; i++) {
      print(t);
      t.change();
    }
  }
} /* Output:
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
*///:~

values()的秘密
  虽然我们之前使用了values方法,但是如果查看Enum,我们并没有发现values方法,那么是不是还有其他隐藏的方法呢?我们可以通过一个简单的反射代码来查看一下:
代码如下:

//: enumerated/Reflection.java
// Analyzing enums using reflection.
import java.lang.reflect.*;
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
enum Explore { HERE, THERE }
public class Reflection {
  public static Set analyze(Class enumClass) {
    print("----- Analyzing " + enumClass + " -----");
    print("Interfaces:");
    for(Type t : enumClass.getGenericInterfaces())
      print(t);
    print("Base: " + enumClass.getSuperclass());
    print("Methods: ");
    Set methods = new TreeSet();
    for(Method m : enumClass.getMethods())
      methods.add(m.getName());
    print(methods);
    return methods;
  }
  public static void main(String[] args) {
    Set exploreMethods = analyze(Explore.class);
    Set enumMethods = analyze(Enum.class);
    print("Explore.containsAll(Enum)? " +
    exploreMethods.containsAll(enumMethods));
    printnb("Explore.removeAll(Enum): ");
    exploreMethods.removeAll(enumMethods);
    print(exploreMethods);
    // Decompile the code for the enum:
    OSExecute.command("javap Explore");
  }
} /* Output:
----- Analyzing class Explore -----
Interfaces:
Base: class java.lang.Enum
Methods:
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
----- Analyzing class java.lang.Enum -----
Interfaces:
java.lang.Comparable
interface java.io.Serializable
Base: class java.lang.Object
Methods:
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
Explore.containsAll(Enum)? true
Explore.removeAll(Enum): [values]
Compiled from "Reflection.java"
final class Explore extends java.lang.Enum{
public static final Explore HERE;
public static final Explore THERE;
public static final Explore[] values();
public static Explore valueOf(java.lang.String);
static {};
}
*///:~

我们可以看到values方法是被编译器添加的。valueOf方法也是在创建枚举的时候由编译器添加的,但是在Enum类中也有一个valueOf方法,但是这个方法有两个参数,而由编译器添加的valueOf方法只有一个参数。枚举被编译器解释为final,因此枚举不能被继承。因为values方法是被编译器添加的静态方法,因此如果你将枚举上塑造型到Enum的时候,values方法将会不可用,但是在Class中有getEnumConstants方法,因此虽然values方法在Enum中不可用,但是还是可以通过Class对象获取枚举的实例:
代码如下:

//: enumerated/UpcastEnum.java
// No values() method if you upcast an enum
enum Search { HITHER, YON }
public class UpcastEnum {
  public static void main(String[] args) {
    Search[] vals = Search.values();
    Enum e = Search.HITHER; // Upcast
    // e.values(); // No values() in Enum
    for(Enum en : e.getClass().getEnumConstants())
      System.out.println(en);
  }
} /* Output:
HITHER
YON
*///:~

实现而不继承
  因为我们定义的枚举类型都继承自java.lang.Enum,而且Java又不支持多重继承,因此不同通过继承创建枚举,但是可以通过继承一个或多个接口创建枚举:
代码如下:

//: enumerated/cartoons/EnumImplementation.java
// An enum can implement an interface
package enumerated.cartoons;
import java.util.*;
import net.mindview.util.*;
enum CartoonCharacter implements Generator {
  SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;
  private Random rand = new Random(47);
  public CartoonCharacter next() {
    return values()[rand.nextInt(values().length)];
  }
}
public class EnumImplementation {
  public static void printNext(Generator rg) {
    System.out.print(rg.next() + ", ");
  }
  public static void main(String[] args) {
    // Choose any instance:
    CartoonCharacter cc = CartoonCharacter.BOB;
    for(int i = 0; i < 10; i++)
      printNext(cc);
  }
} /* Output:
BOB, PUNCHY, BOB, SPANKY, NUTTY, PUNCHY, SLAPPY, NUTTY, NUTTY, SLAPPY,
*///:~

随机选取
  后面我们很多例子中都会用到从枚举实例中随机选取对象,我们创建一个公用类来实现:
代码如下:

//: net/mindview/util/Enums.java
package net.mindview.util;
import java.util.*;
public class Enums {
  private static Random rand = new Random(47);
  public static T random(Class ec) {
    return random(ec.getEnumConstants());
  }
  public static T random(T[] values) {
    return values[rand.nextInt(values.length)];
  }
} ///:~

代码如下:

//: enumerated/RandomTest.java
import net.mindview.util.*;
enum Activity { SITTING, LYING, STANDING, HOPPING, RUNNING, DODGING, JUMPING, FALLING, FLYING }
public class RandomTest {
  public static void main(String[] args) {
    for(int i = 0; i < 20; i++)
      System.out.print(Enums.random(Activity.class) + " ");
  }
} /* Output:
STANDING FLYING RUNNING STANDING RUNNING STANDING LYING DODGING SITTING RUNNING HOPPING HOPPING HOPPING RUNNING STANDING LYING FALLING RUNNING FLYING LYING
*///:~

使用接口进行组织
  枚举不能被继承,这一点有时候会给我们造成不方便,因为有些时候我们想要通过继承来扩展枚举的数量,有些时候我们需要对枚举进行分组。对于后者我们可以通过在接口内定义分组的枚举,然后在通过继承自这个接口来创建枚举,如下我们有不同的食物类需要创建为枚举,但是我们又需要将每个种类定义为Food的类型,如下:
代码如下:

//: enumerated/menu/Food.java
// Subcategorization of enums within interfaces.
package enumerated.menu;
public interface Food {enum Appetizer implements Food {SALAD, SOUP, SPRING_ROLLS;}
  enum MainCourse implements Food {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}
  enum Dessert implements Food {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}
  enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}
} ///:~

因为每个枚举都定义为接口的实现,因此每个枚举都是Food类型,如下:
代码如下:

//: enumerated/menu/TypeOfFood.java
package enumerated.menu;
import static enumerated.menu.Food.*;
public class TypeOfFood {
  public static void main(String[] args) {
    Food food = Appetizer.SALAD;
    food = MainCourse.LASAGNE;
    food = Dessert.GELATO;
    food = Coffee.CAPPUCCINO;
  }
} ///:~

但是接口不能像枚举一样操作多种类型,因此如果你需要一个枚举的枚举,那么你可以在一个枚举里面封装每个枚举类型的一个实例:
代码如下:

//: enumerated/menu/Course.java
package enumerated.menu;
import net.mindview.util.*;
public enum Course {
  APPETIZER(Food.Appetizer.class),MAINCOURSE(Food.MainCourse.class),DESSERT(Food.Dessert.class),COFFEE(Food.Coffee.class);
  private Food[] values;
  private Course(Class

    
 
 

您可能感兴趣的文章:

  • java命名空间java.sql枚举clientinfostatus的类成员方法: valueof定义及介绍
  • java自定义枚举转换器示例
  • java命名空间java.math枚举roundingmode的类成员方法: valueof定义及介绍
  • java中没有枚举变量,类似的功能如何简单实现?
  • java命名空间java.sql枚举rowidlifetime的类成员方法: valueof定义及介绍
  • JAVA 为什么没有枚举类型???
  • java命名空间javax.swing枚举dropmode的类成员方法: valueof定义及介绍
  • java枚举的使用示例
  • java命名空间javax.swing枚举sortorder的类成员方法: valueof定义及介绍
  • java实现高效的枚举元素集合示例
  • java命名空间javax.tools枚举standardlocation的类成员方法: valueof定义及介绍
  • 基于java枚举类综合应用的说明
  • java命名空间javax.xml.ws枚举service.mode成员方法: valueof定义参考
  • 如何用JAVA定义枚举类型的类
  • java命名空间java.lang.management枚举memorytype的类成员方法: valueof定义及介绍
  • java中枚举的详细使用介绍
  • java命名空间java.lang.annotation枚举elementtype的类成员方法: valueof定义及介绍
  • java命名空间java.lang.annotation枚举retentionpolicy的类成员方法: valueof定义及介绍
  • java命名空间java.util.concurrent枚举timeunit的类成员方法: valueof定义及介绍
  • java命名空间java.awt枚举dialog.modalitytype的类成员方法: valueof定义及介绍
  • java命名空间java.net枚举proxy.type的类成员方法: valueof定义及介绍
  • java命名空间javax.xml.ws注释类型webserviceref成员方法: type定义参考
  • java 基本类型或可序列化类型,这里说的可序列化类型是什么意思???具体都有哪些类型??谢谢
  • java命名空间javax.annotation注释类型resource的类成员方法: authenticationtype定义及介绍
  • 如何将java.util.Date类型的日期转换成java.sql.Date类型的日期?
  • java命名空间javax.annotation注释类型resource的类成员方法: type定义及介绍
  • 请问SQL中的datetime类型于java中什么类型对应?
  • java命名空间javax.xml.ws注释类型webserviceref成员方法: value定义参考
  • java中的字符类型如何转换成String类型
  • java命名空间javax.annotation注释类型resource的类成员方法: shareable定义及介绍
  • 请教JAVA小问题:如何将含数字的String类型的对象转化为int或long类型
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 怎么没有讨论XML的?哪位高手介绍介绍在JAVA中怎么使用XML?
  • java命名空间java.beans接口propertyeditor的类成员方法: getvalue定义及介绍
  • 急!!谁了解macintosh?能不能给我介绍介绍?是不是跟linux差不多?使用开发工具JDK,这是不是不JAVA?
  • java命名空间java.awt类container的类成员方法: getlayout定义及介绍
  • 各位高手,我初学java,以前是学VB的,请介绍一下学习java的经验
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 请大家介绍一下java BEAN的入门读物吧
  • java命名空间java.beans类defaultpersistencedelegate的类成员方法: defaultpersistencedelegate定义及介绍
  • 各位高手,我初学java,以前是学VB的,请介绍一下学习java的经验 iis7站长之家
  • java命名空间java.text类decimalformat的类成员方法: topattern定义及介绍
  • 介绍本学 JAVA的好书怎么样?请注明出版社
  • java命名空间java.sql类types的类成员方法: null定义及介绍
  • 介绍一些学习JAVA SWING 方面的好书.
  • java命名空间java.awt类awtevent的类成员方法: id定义及介绍
  • 哪里有Java 2D Graphics方面的介绍?
  • java命名空间java.text类choiceformat的类成员方法: choiceformat定义及介绍
  • 谁能告诉我哪里能找到java包内部类及方法使用介绍
  • java命名空间java.sql类driverpropertyinfo的类成员方法: value定义及介绍
  • 请问那里有java控制图形的介绍和代码?
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: isrepresentationclassinputstream定义及介绍
  • 介绍一本Java好书
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: stringflavor定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向
  • java命名空间java.security类keystore的类成员方法: getdefaulttype定义及介绍




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3