A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 段玉超 中级黑马   /  2012-3-5 16:50  /  2214 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

{:soso_e100:}
回复 使用道具 举报
       我也是刚刚开始学习JAVA,买了一本《JAVA语言程序设计》看起来还不错,不过不知道为什么 这本厚达一千多页的书中竟然没有介绍JAVA的枚举和反射以及内部类,这两个主题。我也是看到论坛的好多帖子才知道 JAVA还有这些东西的。惭愧的很。
     书上没有 就到网上找了找,发现JAVA以前是没有枚举的。jdk1.5之后才有。而且好像JAVA的枚举好像有很多c、C#中没有的特性,比如。在枚举中可以包含方法。看到这里我就想 如果是这样 枚举还是枚举么?这个想法让我想知道JAVA的的枚举类型是怎么实现的呢,为什么它可以添加方法。
     我今天无意间,在jdk源代码 的JAVA.lang 文件夹下发现了 一个很好玩儿的东西 你才是什么?呵呵 马上告诉你 那就是 Enum.JAVA文件,还有另外一个 Enum什么.JAVA  好像是一个异常类型不管他。大家都知道,JAVA的基本类型 int 、big 等在java.lang 包中都有对应的包装类型,可那是java对值类型的包装类,Enum应该是引用类型吧,那这里的Enum.java 是干什么的,少废话,看看不就知道了?说干就干!打开源代码,(悲催,这个编辑器对代码的支持有点儿若呀,不能折叠),原来是 个抽象类。在jdk中找了找 ,好像也没有具体类扩展了他呀,他到底是干什么的呢。稍后再说。
  1. public abstract class Enum<E extends Enum<E>>
  2.         implements Comparable<E>, Serializable {
复制代码
我们先声明一个枚举
  1. enum TestEnum
  2. {
  3.   a, b, c
  4. }
复制代码
上面就是一个枚举了,大家都知道怎么用啦。可是你知道他到底怎么就成为了一个枚举呢,换句话说 它为什么具有了 出了从Object 继承而来的东西之外的东西的(大家都知道 所有的类型都直接或者间接继承Object)。人都是爹妈生的,这玩意儿是哪里来的,凭空而来的么?不知道这个问题大家想过没有,这里看不出来他爹妈是谁,说明了一个问题,他是个私生子,谁的私生子呢?让我们推理一下,我们写的代码,首先要交给谁来处理,没错 javaC 也就是javaC的编译器。编译之后就贵虚拟机调用了,那么不是编译器,就是虚拟及啦。大家都知道 虚拟机不会修改代码的。那肯定是编译器了。编译器直接处理我们编写的代码,那么,编译器对我们的代码进行一些改动那是在方便不过得了。可惜,对于java好像编译之后的文件是字节文件,人看不懂,不过不用急,有办法。
     我们可以利用反编译工具,记住要找一个比较笨的编译器(这个在qq群里讨论过了不再说)。我这里找到一个 推荐个大家叫做CAVAj 已经在群里共享了。
我们把刚才的 TestEnum 代码使用JavaC 反编译,看看反编译的结果,也许你就会大吃一惊 咱们写了这么一点儿代码反编译之后 竟然得到了一大堆

  1. final class TestEnum extends Enum
  2. {

  3.     public static final TestEnum a;
  4.     public static final TestEnum b;
  5.     public static final TestEnum c;
  6.     private static final TestEnum $VALUES[];

  7.     public static TestEnum[] values()
  8.     {
  9.         return (TestEnum[])$VALUES.clone();
  10.     }

  11.     public static TestEnum valueOf(String s)
  12.     {
  13.         return (TestEnum)Enum.valueOf(TestEnum, s);
  14.     }

  15.     private TestEnum(String s, int i)
  16.     {
  17.         super(s, i);
  18.     }

  19.     static
  20.     {
  21.         a = new TestEnum("a", 0);
  22.         b = new TestEnum("b", 1);
  23.         c = new TestEnum("c", 2);
  24.         $VALUES = (new TestEnum[] {
  25.             a, b, c
  26.         });
  27.     }
  28. }
复制代码
看到了吧,这就是 经过编译器编译之后的枚举类型的真是面目。真是面目全飞呀。不过这个时候,以前不理解的东西也许你就理解了。比如为什么 Enum是可比较的(TestEnum 扩展了 JAVA.lang.Enum 而 Enum 实现了 Comparable<E>),为什么可以使用 TestEnum.a 语法。 为什么可以使用 values()方法等等到这里应该都迎刃而解了吧。
   
     以上只是一个我认为的学习的一个方法,共享出来与大家一起进步,我觉得学习编程语言不能拘泥于表象,死记硬背,也不能够只看到表象,一切现象的背后都有其原因。
    我猜想 JAVA的 迭代器,泛型等都是这个原理。都可以使用这个方法看到本质,以后有时间再看把。最后一句偷来的话  :每一个对象都是一个长期,每一个传奇都有一段精彩的故事。
    希望大家学习愉快,进步多多。最大的希望是 老师多给点儿分儿啊 呵呵

评分

参与人数 1技术分 +2 收起 理由
职业规划-刘倩老师 + 2 赞一个!

查看全部评分

1 个回复

倒序浏览
您需要登录后才可以回帖 登录 | 加入黑马