java枚举Enum与Enumeration源码详解

java枚举Enum与Enumeration源码详解

类的定义

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
}

属性定义

    private final String name;

    public final String name() {
        return name;
    }

    private final int ordinal;

    public final int ordinal() {
        return ordinal;
    }

    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    public String toString() {
        return name;
    }

    public final boolean equals(Object other) {
        return this==other;
    }
    public final int hashCode() {
        return super.hashCode();
    }

    protected final Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    public final int compareTo(E o) {
        Enum<?> other = (Enum<?>)o;
        Enum<E> self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

    @SuppressWarnings("unchecked")
    public final Class<E> getDeclaringClass() {
        Class<?> clazz = getClass();
        Class<?> zuper = clazz.getSuperclass();
        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
    }

    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }


    protected final void finalize() { }


    private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
        throw new InvalidObjectException("can't deserialize enum");
    }

    private void readObjectNoData() throws ObjectStreamException {
        throw new InvalidObjectException("can't deserialize enum");
    }
  1.  使用final修饰 无疑会在内存上有稍多的消耗,因为final修饰后的属性所在的常量池。

    常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量和符号引用。运行时常量池是方法区的一部分。 

    常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量: 

        1.类和接口的全限定名 

        2.字段名称和描述符 

        3.方法名称和描述符

Java中八种基本类型的包装类的大部分都实现了常量池技术,它们是Byte、Short、Integer、Long、Character、Boolean,另外

两种浮点数类型的包装类(Float、Double)则没有实现。另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在

对应值在-128到127时才可使用对象池

final 修饰属性:则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一)。

     2. 比较两个枚举类型的值,永远不需要调用equals,直接使用"=="就可以了。

     3. 所有的枚举类型都是Enum的子类,继承了许多的方法,其中最有用的就是toString方法,这个方法能返回枚举常量名。如SeasonEnum.SPRING.toString返回SPRING

     4. toString的逆方法是静态方法valueof。例如 SeasonEnum s = Enum.valueof(SeasonEnum.class,“SPRING”),将s设置为SeasonEnum.SPRING

     5. ordinal方法返回enum声明中枚举常量的位置,位置从0开始计数,例如SeasonEnum.SUMMER.ordinal()返回1.

     6.类型参数在CompareTo方法中的使用,如同Class类一样,鉴于简化的考虑,Enum类省略了一个类型参数。实际上,应将枚举类型SeasonEnum扩展为Enum<SeasonEnum>。如果枚举常量出现在other之前,则返回一个负值;如果this==other,则返回0;否则返回正值,枚举常量的出现次序在enum声明中给出。

     7. 因为equals、hashcode方法是被final修饰的,所以不可以被枚举重写(只可以继承),但是,可以重写toString方法。

先来看看Java枚举的基本使用

如果我们冒然的提供set方法(外界可以改变其成员属性),好像是有点违背了设计的初衷。那么,我们应该舍弃set方法,保留get方法。

枚举是什么?

  Java中的枚举其实是一种语法糖,在 JDK 1.5之后出现,用来表示固定且有限个的对象。比如一个季节类有春、夏、秋、冬四个对象;一个星期有星期一到星期日七个对象。这些明显都是固定的,且有限个。

枚举类和普通类的区别

  ①、使用 enum 定义的枚举类默认继承 java.lang.Enum 类,即枚举类是不能再继承别的类了。而普通类的一般父类默认是 Object

  ②、枚举类的构造器只能使用 private 定义,而普通类的还可以用 public 修饰

  ③、枚举类的所有实例必须在枚举类中显示列出(,分隔   ;结尾),列出的实例系统会默认自动添加 public static final 修饰

  ④、所有的枚举类都提供了一个 values() 方法,可以用来遍历枚举值

使用 Enum 来表示季节类:

public enum SeasonEnum {
	 
    //必须在第一行写出有哪些枚举值
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "炎炎盛夏"),
    FALL("秋天", "秋高气爽"),
    WINTER("冬天", "大雪纷飞");
     
    private final String name;
    private final String desc;
     
    private SeasonEnum(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
     
    public static void main(String[] args) {
        
        System.out.println(SeasonEnum.SPRING); //SPRING
        //用 values() 来获取所有的枚举值
        for(SeasonEnum s : SeasonEnum.values()){
            System.out.println(s);
        }
    }    
}

枚举类还能实现接口:

定义一个接口,方法是返回季节的月份

public interface SeasonEnumImpl {
    //用来返回季节的月份
    String getMonth();
 
}
public enum SeasonEnum implements SeasonEnumImpl{
	 
    //必须在第一行写出有哪些枚举值
    SPRING("春天", "春暖花开"){
        @Override
        public String getMonth() {
            return "12-2";
        }
    },
    SUMMER("夏天", "炎炎盛夏"){
        @Override
        public String getMonth() {
            return "3-5";
        }
    },
    FALL("秋天", "秋高气爽"){
        @Override
        public String getMonth() {
            return "6-8";
        }
    },
    WINTER("冬天", "大雪纷飞"){
        @Override
        public String getMonth() {
            return "9-11";
        }
    };
     
    private final String name;
    private final String desc;
     
    private SeasonEnum(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
    
    public static void main(String[] args) {
        
        System.out.println(SeasonEnum.SPRING); //SPRING
         
        //用 values() 来获取所有的枚举值
        for(SeasonEnum s : SeasonEnum.values()){
            System.out.println(s.getMonth());
        }
    }
    
}

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。 

public enum Fruit {
	APPLE, BANANA, ORANGE, WATERMELON;
}
public class EnumTest {
    public static void main(String[] args)
    {
        for(Fruit fruit : Fruit.values())
        {
            test(fruit);
        }
    }
     
    public static void test(Fruit fruit)
    {
        switch (fruit)
        {
            case APPLE:
                System.out.println("This is an apple");
                break;
            case BANANA:
                System.out.println("This is a banana");
                break;
            case ORANGE:
                System.out.println("This is an orange");
                break;
            case WATERMELON:
                System.out.println("This is a watermelon");
                break;
 
            default:
                break;
        }
    }
}

Enumeration类源码

public interface Enumeration<E> {

    boolean hasMoreElements();


    E nextElement();
}

遍历枚举类

Map map = request.getParameterMap();    
java.util.Enumeration  enum=this.getRequest().getParameterNames();    
       while(enum.hasMoreElements()){    
                  String  paramName=(String)enum.nextElement();                        
                  String[]  values=request.getParameterValues(paramName);    
                  for(int  i=0;i<values.length;i++){    
                  System.out.println("["+i+"]   "+paramName+"  "+values[i]);   
                  }   
       }  

   //形成键值对应的map  
  map.put(paramName, paramValue);  
  }  

​

Mybatis中的枚举

发布了370 篇原创文章 · 获赞 88 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/qq_35029061/article/details/100190890