我也是刚刚开始学习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中找了找 ,好像也没有具体类扩展了他呀,他到底是干什么的呢。稍后再说。- public abstract class Enum<E extends Enum<E>>
- implements Comparable<E>, Serializable {
复制代码 我们先声明一个枚举- enum TestEnum
- {
- a, b, c
- }
复制代码 上面就是一个枚举了,大家都知道怎么用啦。可是你知道他到底怎么就成为了一个枚举呢,换句话说 它为什么具有了 出了从Object 继承而来的东西之外的东西的(大家都知道 所有的类型都直接或者间接继承Object)。人都是爹妈生的,这玩意儿是哪里来的,凭空而来的么?不知道这个问题大家想过没有,这里看不出来他爹妈是谁,说明了一个问题,他是个私生子,谁的私生子呢?让我们推理一下,我们写的代码,首先要交给谁来处理,没错 javaC 也就是javaC的编译器。编译之后就贵虚拟机调用了,那么不是编译器,就是虚拟及啦。大家都知道 虚拟机不会修改代码的。那肯定是编译器了。编译器直接处理我们编写的代码,那么,编译器对我们的代码进行一些改动那是在方便不过得了。可惜,对于java好像编译之后的文件是字节文件,人看不懂,不过不用急,有办法。
我们可以利用反编译工具,记住要找一个比较笨的编译器(这个在qq群里讨论过了不再说)。我这里找到一个 推荐个大家叫做CAVAj 已经在群里共享了。
我们把刚才的 TestEnum 代码使用JavaC 反编译,看看反编译的结果,也许你就会大吃一惊 咱们写了这么一点儿代码反编译之后 竟然得到了一大堆
- final class TestEnum extends Enum
- {
- public static final TestEnum a;
- public static final TestEnum b;
- public static final TestEnum c;
- private static final TestEnum $VALUES[];
- public static TestEnum[] values()
- {
- return (TestEnum[])$VALUES.clone();
- }
- public static TestEnum valueOf(String s)
- {
- return (TestEnum)Enum.valueOf(TestEnum, s);
- }
- private TestEnum(String s, int i)
- {
- super(s, i);
- }
- static
- {
- a = new TestEnum("a", 0);
- b = new TestEnum("b", 1);
- c = new TestEnum("c", 2);
- $VALUES = (new TestEnum[] {
- a, b, c
- });
- }
- }
复制代码 看到了吧,这就是 经过编译器编译之后的枚举类型的真是面目。真是面目全飞呀。不过这个时候,以前不理解的东西也许你就理解了。比如为什么 Enum是可比较的(TestEnum 扩展了 JAVA.lang.Enum 而 Enum 实现了 Comparable<E>),为什么可以使用 TestEnum.a 语法。 为什么可以使用 values()方法等等到这里应该都迎刃而解了吧。
以上只是一个我认为的学习的一个方法,共享出来与大家一起进步,我觉得学习编程语言不能拘泥于表象,死记硬背,也不能够只看到表象,一切现象的背后都有其原因。
我猜想 JAVA的 迭代器,泛型等都是这个原理。都可以使用这个方法看到本质,以后有时间再看把。最后一句偷来的话 :每一个对象都是一个长期,每一个传奇都有一段精彩的故事。
希望大家学习愉快,进步多多。最大的希望是 老师多给点儿分儿啊 呵呵
|