疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java面向对象之枚举详解


 

   

  一、前言

  今天我们来讲讲枚举,希望通过这篇博客大家能对枚举有个更全面的了解。枚举是一种实例(大写)数固定的类(不能再创建实例),多用于确定的状态数(如:鼠标上下左右、IM消息已读未读)、类型数(如:系统、聊天、添加好友消息,我的他的)、模式数(回复、评论模式,刷选、全部模式)等等。枚举和类一样,同样有抽象类、可以实现接口、可含内部类、初始化块,值得注意的是:枚举的构造器无论是否使用private修饰,默认总是被private修饰;当然,枚举变量也可以在switch使用。下面我们通过实例来全面了解一下Java中的枚举。

  二、实例说明

  (1)实例演示

  [java] view plaincopy在CODE上查看代码片派生到我的代码片

  /**

  * 修饰符 enum 枚举名{

  * //立即在第一行列出该枚举的所有实例(但实际上是创建枚举实例,会默认调用无参构造器)。

  * }

  *

  */

  public enum Gender {

  // MALE("男")相当于:Gender MALE = new Gender("男");

  // 列出所有枚举值,也就是该枚举所有可能的实例--实例列表

  // WOMENMALE其实默认就是WOMENMALE()

  MALE("男"), FEMALE("女"), MANMALE(), WOMENMALE;

  private String name;

  // --构造器无论是否使用private修饰,默认总是被private修饰

  Gender() {

  System.out.println("无参构造方法被调用...");

  }

  private Gender(String name) {

  System.out.println("含参构造方法被调用..." + name);

  this.name = name;

  }

  // 注意:初始化块只能被static修饰。

  // 编译时实例初始化块的代码都会被提取到构造器的“最前面”,所以它执行的优先级高于构造器

  {

  System.out.println("实例初始化块....");

  }

  // 当类被加载后,对类初始化后时被隐式执行,且一个JVM对一个类只初始化一次。

  static {

  System.out.println("静态/类初始化块...");

  }

  public void info() {

  System.out.println(this + " 枚举中的info方法被调用");

  }

  /**

  * 枚举在switch中的使用 --switch(byte/short/char/int/String/枚举)

  *

  * @param gender

  */

  public static void chooseSex(Gender gender) {

  switch (gender) {// 传一个枚举变量给switch

  case MALE:

  System.out.println("男性...");

  break;

  case FEMALE:

  System.out.println("女性...");

  break;

  case MANMALE:

  System.out.println("男同...");

  break;

  case WOMENMALE:

  System.out.println("女同...");

  break;

  default:

  break;

  }

  }

  class A {

  {

  System.out.println("A中实例初始化块...");

  }

  public void info() {

  System.out.println(this + "A类中的info方法被调用");

  }

  }

  public static void main(String[] args) {

  // 初始化块及构造器(无参或含参)按实例列表顺序挨个被执行,接着执行静态(类)初始化块

  Gender g1 = Gender.MALE;

  Gender.chooseSex(g1);

  g1.info();

  // 创建寄生类(内部类)实例

  A a = g1.new A();

  a.info();

  // 打印该枚举变量g1所在的实例列表所在的位置,从0开始

  System.out.println(g1.ordinal());

  // Gender g2 = Gender.FEMALE;

  // System.out.println(g2.ordinal());

  // 打印该枚举的所有实例

  for (Gender g : Gender.values()) {

  System.out.println(g);

  }

  }

  }

  ========= 打印结果 =============

  实例初始化块....

  含参构造方法被调用...男

  实例初始化块....

  含参构造方法被调用...女

  实例初始化块....

  无参构造方法被调用...

  实例初始化块....

  无参构造方法被调用...

  静态/类初始化块...

  男性...

  MALE 枚举中的info方法被调用

  A中实例初始化块...

  com.leo.enumation.Gender$A@c17164A类中的info方法被调用

  0

  MALE

  FEMALE

  MANMALE

  WOMENMALE

  (2)下面看看抽象枚举的使用

  [java] view plaincopy在CODE上查看代码片派生到我的代码片

  // 编译器将把注解信息记录在class文件中,当运行Java程序时JVM会保留注解,因此可以通过反射机制来读取注解的信息。

  @Retention(RetentionPolicy.RUNTIME)

  // 注解作用在类上面

  @Target(ElementType.TYPE)

  public @interface ClassName {

  // 声明默认值

  String name() default "计算";

  // 特殊的值

  String value();

  }

  [java] view plaincopy在CODE上查看代码片派生到我的代码片

  /**

  * 利用抽象枚举来模拟一个四则运算,需要创建匿名内部类来重写相关抽象方法。

  *

  */

  // 指定用的是哪个自定义注解的类,若把name去掉,则name默认为:计算

  @ClassName(name = "枚举", value = "四则运算")

  public enum Calculator {

  ADD("张三") {

  @Override

  public double eval(double x, double y) {

  return x + y;

  }

  },

  SUB {

  @Override

  public double eval(double x, double y) {

  return x - y;

  }

  },

  MULTIPLY {

  @Override

  public double eval(double x, double y) {

  return x * y;

  }

  },

  DIVIDE {

  @Override

  public double eval(double x, double y) {

  if (y == 0) {

  throw new ArithmeticException("除数不能为0");

  }

  return x / y;

  }

  };

  private String name;

  private Calculator() {

  System.out.println("无参构造器被执行..." + this);

  }

  private Calculator(String name) {

  this.name = name;

  System.out.println("含参构造器被执行..." + this.name);

  }

  public abstract double eval(double x, double y);

  public static void main(String[] args) throws ClassNotFoundException {

  Calculator c1 = Calculator.ADD;

  System.out.println(c1.eval(1, 2));

  // Calculator c2 = Calculator.SUB;

  // System.out.println(c2.eval(1, 2));

  // 打印该枚举的一些注解信息

  Class clazz = Class.forName("com.leo.enumation.Calculator");

  ClassName cn = clazz.getAnnotation(ClassName.class);

  System.out.println(cn.name() + " ," + cn.value());

  }

  }

  (3)枚举实现接口

  [java] view plaincopy在CODE上查看代码片派生到我的代码片

  interface IDirection {

  void pointDirection();

  }

  /**

  * 枚举实现接口

  *

  */

  public enum Orientation implements IDirection {

  EAST, WEST, SOUTH(), NORTH;

  @Override

  public void pointDirection() {

  System.out.println("指向 ---> " + this);

  }

  public static void main(String[] args) {

  IDirection direction = Orientation.SOUTH;

  direction.pointDirection();

  }

  }

  三、总结

  关于Java中的枚举相关知识点大体就这些了,后面讲陆续更新内部类、正则表示式、改善Java代码质量的一些建议等等,敬请关注!