Enum开锁

1,662 views
1,542 views

Published on

java Enum

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,662
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 1 )为何 Enum 声明为 abstract ,我也不很清楚。可能是限制我们对 Enum 的使用,也可能是给编译器用的,类似于某些标记接口。 2 )这个泛型表达式表示 泛型参数型必须是 Enum 泛型类的子类,这个地方要看看 java 规范,了解的不深。 弄清楚关于泛型的几个术语: 1. Type Parameters 2. Type Variables 3. Type Arguments 4. Parameterized Types 5. Bounds
  • Enum开锁

    1. 1. 开锁项目技术总结 hongjiang 2009.9.3
    2. 2. com.alibaba.common.lang.enumeration.Enum 为何会导致死锁 ?JVM 规范:类初始化过程是唯一的。当多个线程同时对某个类进行初始化时,只有一个线 程能够进行了 clinit ,其他线程会检测并等待,当 发现类已经被初始化完毕了它们不会再次执行 clinit 。简单的说,导致死锁的原因是因为线程 A 在对我们的 Enum 中进行 clinit 时调用的方法要获取一个锁 L ,而锁 L 正被线程 B 占用,同时线程 B 又正要访 问这个 Enum 类成员,发现 Enum 类正在被线程 A 初始化,于是线程 B 等待线程 A 。 结果成了相互等待。
    3. 3. 解决方式将继承自 com.alibaba.common.lang.enumeration. Enum的枚举,改用 Java5 中的 enum 类型来实现。
    4. 4. Java5 中的 enum 关键字用 enum 关键字定义的一个枚举类型并不是真 的在 java 中创建了一种新的类型, enum 类型本质上仍是一个 class把它当作一种特殊的 class 来对待。( 编译器在会将 enum 转换为 class)在 C, C# 中 enum 类型都是作为值类型的, 而 java 中 enum 是引用类型;
    5. 5. 关于 Java.lang.EnumEnum 是所有 Java 语言枚举类型的公共基本类 :public abstract class Enum<E extends Enum<E>> implements Comparable<E>, SerializableEnum 被标记为 abstract ,但实际上并没有包含 任何 abstract 方法。这是为何?所使用的泛型表达式又如何理解?
    6. 6. 关于 Java.lang.EnumEnum 实现了 Comparable 和 Serializable 接口。Enum 的构造函数是 protected 。protected Enum(String name,int ordinal)除了 toString 方法,其他方法都是 final 的。用户不能自行继承 Enum 类,编译报错。只能通过 enum 来定义枚举。
    7. 7. Java.lang.Enum 的 name() 方法返回此枚举常量的名称,在其枚举声明中对其 进行声明。 与此方法相比,大多数程序 员应该优先考虑使用 toString() 方法 ,因为 toString 方法返回更加用户友 好的名称。该方法主要设计用于特殊情形 ,其正确性取决于获取正确的名称,其名称 不会随版本的改变而改变。
    8. 8. enum 中的静态方法 : valueOf,valuesJava.lang.Enum 中包含:public static <T extends Enum<T>> T valueOf(Class <T> enumType, String name)对于每个继承 Enum 的实际枚举,编译器会自动增加一个静态的方法:public static <T extends Enum<T>> T valueOf(String name)相比 Enum 的 valueOf 少了第一个 enumType 参数,因为这个已经是 确定的了。values() 静态方法:这个静态方法 java.lang.Enum 中没有,是编译器 增加到 enum 中的,返回枚举数组。
    9. 9. 当 enum 出现在内部类中时:public class MyClass{ enum MyEnum{ A,B,C}}上面代码和 enum 前有 static 修饰符的效果 是一样的。
    10. 10. enum 获取某个属性的方式1) 定义该属性为成员变量,在构造函数中设置该属性,通过 getXXX 方式来获取。 eg:public enum OfferTypeEnum { /** 求购 */ SALE("SALE"), /** 供应 */ BUY("BUY"), /** 类型:合作 */ MISC("MISC"), …… public String getName() { return this.name; }
    11. 11. 2) Switch 方式判断。(容易维护) public enum OfferTypeEnum { SALE, BUY, MISC; public String getName() { switch(this){ case SALE: return "SALE"; case BUY: return "BUY"; case MISC: return "MISC"; } return ""; } 效率方面,第 2 种每次都需要比较,第 1 种采用空间换时间的方式 。 我们采用第一种方式。
    12. 12. 将字符串解析为 enumEnumUtil 工具类中的 getEnumByName ,等方法 返回值都是旧的 Enum 类型。对应的,增加了 JdkEnumUtil 工具类使用 其中的 valueOf 函数来将字符串解析为新的枚 举。但对于那些枚举变量名和 name 属性不一致的情况, 应该在相应的枚举中提供 parse 方法,比如:
    13. 13. OfferTypeEnum 中:/** 类型:代理 */AGENT(“AGEN”), // 这里是前人犯的错误,兼容以前的代码需要该类自行提供一个解析方法:public static OfferTypeEnum parse(String str){ if(str == null) return null; if (str.equals("AGEN") || str.equals("AGENT")) return AGENT; return (OfferTypeEnum)JdkEnumUtil.valueOf(OfferTyp eEnum.class, str);}
    14. 14. 遇到继承的问题旧的 Enum 有一些是有继承关系的,一个实际的例子,比如:TypeEnum 有两个子类DangerousKeywordTypeOfferCategoryEnum可以将原先的父类改为 interface, enum 可以 实现接口。
    15. 15. Java5 的 enum 为何不能继承? 会员类型: 免费会员 中文站会员类型: 国际站会员类型: Free+, 诚信通 中供Java5 的 enum 是不可以继承的,无法通过继承的方式来复用,因为它破坏 了类型的一致性。子类和父类类型不同。枚举的值必须是相同类型enum 类型的 class.getModifiers() 是包含 final 修饰符的。(编译器将 enum 转为 final class ,确保它无法继承。 )
    16. 16. toolkit-biz-command-jdk-enumToolkit-biz-command-jdk-enum 是宝宝用 Java5 枚 举重写的一个包,不过考虑改动尽可能的 小, Exodus2 中并没有使用这个包。注意 ResultCodeUtil.java 中的 getName 方法使用了 Enum 的 name() 方法,实际中有些枚举变量 名称和 name 值是不同的,如果使用要避免使用 ResultCodeUtil.getName 方法。
    17. 17. 使用 shell 来检测重构后枚举名称是否写错 Distill-trunk.sh Distill-branch.sh Javafile Checknew.sh Checkunmatchedref.sh Getunmatched.sh

    ×