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");
}
- 使用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中的枚举
标签:SeasonEnum,java,String,Enum,final,枚举,源码,public,name From: https://blog.51cto.com/u_11837698/6081992