`
啸笑天
  • 浏览: 3462482 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

12-16 jdk5枚举

阅读更多

 

模拟枚举,其实枚举编译后就是如此:

 

 

package cn.zyj13.review;

public class EnumTest {
	public static void main(String[] args) {
		WeekDay mon=WeekDay.MON;
		System.out.println(mon);
		System.out.println(mon.nextDay());

	}

}

package cn.zyj13.review;

public abstract class WeekDay {
	//1、私有构造函数  
	private WeekDay(){}
	//2、每个元素分别用一个公有的静态成员变量表示
	public final static WeekDay MON =new WeekDay() {
		//3、可以有若干个公有方法或抽象方法。  
		//例如,要提供nextDay()方法必须是抽象的。采用抽象方法定义的nextDay()就将大量的ifelse语句转移成了一个个独立的类  
		@Override
		public WeekDay nextDay() {
			return TUE ;
		}
		@Override
		public String toString() {
			return "Monday";
		}
	};
	
	public final static WeekDay TUE =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return WED ;
		}
		@Override
		public String toString() {
			return "Tuesday";
		}
	};
	
	public final static WeekDay WED =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return THU ;
		}
		@Override
		public String toString() {
			return "Wednesday";
		}
	};
	
	public final static WeekDay THU =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return FRI ;
		}
		@Override
		public String toString() {
			return "Thursday";
		}
	};
	
	public final static WeekDay FRI =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return SAT ;
		}
		@Override
		public String toString() {
			return "Friday";
		}
	};
	
	public final static WeekDay SAT =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return SUN ;
		}
		@Override
		public String toString() {
			return "Saturday";
		}
	};
	
	public final static WeekDay SUN =new WeekDay() {
		@Override
		public WeekDay nextDay() {
			return MON ;
		}

		@Override
		public String toString() {
			return "Sunday";
		}
	};
	public abstract WeekDay nextDay();
	
	public abstract String toString();
//	public String toString(){
//		if (this==Mon) {
//			return "Monday";
//		} else if(this==Tue){
//			return "Tuesday";
//		}else if(this==Wed){
//			return "Wednesday";
//		}else if(this==Thu){
//			return "Thursday";
//		}else if(this==Fri){
//			return "Friday";
//		}else if(this==Sat){
//			return "Saturday";
//		}else{
//			return "Sunday";
//		}
//	}
}

 

 

 

枚举实例:

package cn.zyj1416.review;

public class EnumTest {

	public static void main(String[] args) {
		Weekday weekday1=Weekday.FRI;  
        System.out.println(weekday1);//枚举自动实现toString方法  //FRI
        System.out.println(weekday1.name());  //FRI
        System.out.println(weekday1.ordinal());//注意这个结果//5
        System.out.println(Weekday.MON);  //MON
        System.out.println(Weekday.valueOf("MON"));  //MON
        System.out.println(Weekday.values().length); //7
        
        TrafficLamp red=TrafficLamp.RED;
        System.out.println(red);

	}
	
	 public enum Weekday{  
	        SUN(1),MON(),TUE,WED,THU,FRI,SAT;//元素列表必须放在首行  
	        private Weekday(){System.out.println("first");}//构造函数必须私有  
	        private Weekday(int day){System.out.println("second");}  
	    }  
	 public enum TrafficLamp{
		 //内部类。如果枚举元素后面没有大括号对,那是不会生成内部类的。
			RED(30){
				public  TrafficLamp nextLamp(){
					return GREEN;
				}
			},
			GREEN(45){
				public  TrafficLamp nextLamp(){
					return YELLOW;
				}			
			},
			YELLOW(5){
				public  TrafficLamp nextLamp(){
					return RED;
				}			
			};
			public abstract TrafficLamp nextLamp();
			private int time;
			private TrafficLamp(){}
			private TrafficLamp(int time){this.time = time;}
			public String toString(){
				if (this==RED) {
					return "红";
				} else if(this==GREEN){
					return "绿";
				}else{
					return "黄";
				}
			}
		}
}
 

 

一、为什么要有枚举

枚举就是要让某个类型的变量的取值只能为了若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译的时候就可以控制源程序中填写的非法值,普通变量的方式在开发阶

 

段无法实现这一目标

 

二、用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能

1、私有构造函数

2、每个元素分别用一个公有的静态成员变量表示

3、可以有若干个公有方法或抽象方法。例如,要提供nextDay()方法必须是抽象的。采用抽象方法定义的nextDay()就将大量的ifelse语句转移成了一个个独立的类

 

三、枚举的基本应用

举例:定义一个Weekday的枚举

扩展:所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法。

       (1)  ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。

                 Color.RED.ordinal();  //返回结果:0

                 Color.BLUE.ordinal();  //返回结果:1

       (2)  compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值

 

必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)

                 Color.RED.compareTo(Color.BLUE);  //返回结果 -1

       (3)  values()方法: 静态方法,返回一个包含全部枚举值的数组。

                 Color[] colors=Color.values();

                 for(Color c:colors){

                        System.out.print(c+",");

                 }//返回结果:RED,BLUE,BLACK YELLOW,GREEN,

       (4)  toString()方法: 返回枚举常量的名称。

                 Color c=Color.RED;

                 System.out.println(c);//返回结果: RED

       (5)  valueOf()方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。

                 Color.valueOf("BLUE");   //返回结果: Color.BLUE

       (6)  equals()方法: 比较两个枚举类对象的引用。

总结:枚举是一种特殊的类,而且是一个不可以被继承的final类。其中的每个元素都是该类的一个实例对象,而且是该类的类型的类静态常量,例如可以调用WeekDay.SUN.getClass().getName()WeekDay.class.getName()                                       

 

1、枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

2、枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后面有分号于其他成员隔开。把枚举中的成员方法(包括构造方法)和变量等放在枚举元素额度前面,编译器报告错误。

3、带构造方法的枚举

构造方法必须定义成私有的。这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域

 

可以允许外部访问。

如果有多个构造方法,改如何选择哪个构造方法?

枚举元素MONMON()的效果一样,都是调用默认的构造方法。

4、带方法的枚举

定义枚举TrafficLamp

实现普通的next方法。

实现抽象的next方法;每个元素分别是有枚举类的子类来生成额度实例对象,这些子类采用类似内部类的方法进行定义。

增加上表示时间的构造方法。

5、枚举只有一个成员时,就可以作为一种单例的实现方法。

单例是日常开发中经常会碰到的一种模式,最常见的写法如下所示:

Java代码 

public class Singleton { 

    private Singleton() {} 

    private static final class  Holder { 

        static final Singleton instance = new Singleton(); 

    } 

    public static Singleton getInstance() { 

        return Holder.instance; 

    } 

} 

这样写不仅达到了单例的效果,而且还是延迟加载,至于为什么不明白的童鞋可以 google 百度一下。( 这称为 lazy initialization holder class 模式 )

其实使用枚举可以很容易地实现单例。

Java代码 

public enum Singleton { 

    INSTANCE { 

        public void someMethod() { 

            // . . . 

        } 

    }; 

    protected abstract void someMethod(); 

} 

枚举类型 INSTANCE 就是一个单例,类型为 Singleton

注:双检查锁只有在 jdk 1.5 及以上版本才能达到单例的效果的。

6、枚举类可以在switch语句中使用。

7、枚举实现接口

所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

Java代码

public interface Behaviour { 

    void print(); 

    String getInfo(); 

} 

public enum Color implements Behaviour{ 

    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; 

    } 

//接口方法 

    @Override 

    public String getInfo() { 

        return this.name; 

    } 

    //接口方法 

    @Override 

    public void print() { 

        System.out.println(this.index+":"+this.name); 

    } 

} 

8、使用接口组织枚举

public interface Food { 

    enum Coffee implements Food{ 

        BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO 

    } 

    enum Dessert implements Food{ 

        FRUIT, CAKE, GELATO 

    } 

} 

9、关于枚举集合的使用

java.util.EnumSetjava.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 keyenum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里

 

赘述,可以参考JDK文档。

关于枚举的实现细节和原理请参考:《ThinkingInJava》第四版

 

因为枚举元素必须在定义之后引用,所以无法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    jdk1.6--jdk-6u45-windows-i586.exe.zip

    2. **枚举**:枚举类型是Java 1.5引入的新特性,它提供了一种更安全、更方便的方式来表示一组固定值的集合。 3. **自动装箱与拆箱**:自动装箱允许基本数据类型与对应的包装类之间无缝转换,简化了编程。 4. **...

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 12. JDK内置的三个基本注解.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 12. JDK内置的三个基本注解.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 16. jdk8新特性:可重复注解.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 16. jdk8新特性:可重复注解.avi

    jdk-8u71-windows-x64.exe

    - Type安全的枚举类:允许在枚举类中使用泛型。 2. **JDK的组成部分**: - JRE:包含Java虚拟机(JVM)、Java核心类库和其他必要的组件,用于运行Java应用程序。 - Bin目录:存放Java开发工具,如javac、java、...

    java-jdk1.7-jdk-7u80-windows-x64.zip

    1. **Strings in Switch语句**:在Java 7中,字符串可以被用作switch语句的条件,使得处理枚举类型或字符串常量的代码更加简洁。 2. **多路返回值**:使用`钻石操作符(Diamond Operator)`,在创建泛型实例时可以...

    json-lib-2.4-jdk15.jar

    5. **性能优化**:`json-lib`针对不同的JDK版本(如这里的`jdk15`)进行了优化,以提供最佳的性能和兼容性。 6. **兼容性**:由于`json-lib-2.4-jdk15.jar`是针对JDK15的,因此它应该能很好地运行在Java 1.5及更高...

    json-lib-2.4-jdk15及其依赖jar包

    这个版本是针对JDK 1.5设计的,因此它兼容运行在Java 5及更高版本的环境。`json-lib`库广泛应用于Web服务和分布式系统中,因为JSON作为数据交换格式,其体积小、解析速度快,比XML更为便捷。 这个压缩包可能包含了`...

    JAVA-虚拟机JDK1.5

    JDK1.5以前,Java没有内置的枚举类型。1.5版本中引入了枚举,它是一种特殊的类,可以用于定义一组固定的常量。枚举增强了代码的可读性和安全性。 4. **变长参数(Varargs)** 变长参数允许方法接受任意数量的相同...

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 17. jdk8新特性:类型注解.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 17. jdk8新特性:类型注解.avi

    json-lib-2.1-jdk15-javadoc.zip

    JSON-Lib是一个Java库,用于处理JSON数据,而“json-lib-2.1-jdk15-javadoc.zip”则是JSON-Lib 2.1版本针对JDK 1.5的API文档压缩包。 这个压缩包包含了一系列的HTML文件,它们是Javadoc生成的文档,提供了JSON-Lib ...

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 15. jdk中4个基本的元注解的使用2.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 15. jdk中4个基本的元注解的使用

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 14. jdk中4个基本的元注解的使用1.avi

    计算机后端-Java-Java核心基础-第23章 枚举类与注解 14. jdk中4个基本的元注解的使用

    jdk-1_5_0_17-windows-i586-p.rar_JDK安装包_jdk-1-5-0-07_jdk-1_5_0_17

    JDK 1.5(代号Tiger)引入了许多重要的新特性,如增强的for循环(foreach),枚举类型,泛型,匿名内部类的改进,动态代理等,这些特性极大地提高了Java的生产力和代码的可读性。 总结来说,JDK 1.5.0_17是Java开发...

    json lib jdk

    JDK 1.5是Java的一个重要版本,引入了诸如泛型、枚举、匿名内部类的改进以及自动装箱拆箱等特性,这些特性对JSON Lib的实现和使用有着直接影响。 `json-lib-2.4-jdk15.jar` 这个文件名表明这是一个特定版本的JSON ...

    jdk-16_linux-x64_bin.zip

    5. **安装与配置**:在Linux环境下,解压 "jdk-16_linux-x64_bin.tar.gz" 后,通常需要将JDK的路径添加到系统的PATH环境变量中,以便在命令行中可以随时调用Java命令。 为了使用这个JDK,用户首先需要解压缩zip文件...

    jdk-1_5_0_22-windows-amd64

    3. **枚举类型(Enums)**:JDK 1.5引入了枚举作为一种新的数据类型,使得常量集合更易管理和维护,增强了代码的可读性和安全性。 4. **变量注解(Annotations)**:注解是一种元数据,可以提供有关程序元素(如类...

    jdk-1_5_0_22-linux-amd64安装板(rpm).zip

    这个压缩包“jdk-1_5_0_22-linux-amd64安装板(rpm).zip”包含了适用于Linux操作系统64位架构的JDK 1.5.0_22版本的安装程序。 JDK 1.5,也被称为Java SE 5.0,是Java平台的重大更新,发布于2004年9月。这个版本...

    jdk-7u-1.7.0.0-32 jdk 1.7 免安装版

    5. **文件系统API增强**:NIO.2(New IO 2.0)是Java 7的重要改进,提供了对文件系统更全面的操作,如Path类、Files类和FileVisitor接口等,增强了文件操作的灵活性和安全性。 6. **改进的类型推断**:Java 7的...

    jdk-1_5_0_22-linux-amd64.bin

    2. **枚举类型**:Java 5引入了枚举作为替代常量集合的更安全和强大的方式,提供了更好的类型检查和防止非法值。 3. **自动装箱与拆箱**:自动装箱允许基本数据类型与它们对应的包装器类型之间无缝转换,简化了代码...

    jdk-1_5_0_20-windows-i586-p.exe

    标题“jdk-1_5_0_20-windows-i586-p.exe”指的是Java Development Kit(JDK)的特定版本,这里是1.5.0_20,针对Windows操作系统,且是32位(i586)的版本。JDK是Oracle公司提供的用于开发和运行Java应用程序的基础...

Global site tag (gtag.js) - Google Analytics