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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张权 中级黑马   /  2013-4-28 19:20  /  1966 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张权 于 2013-4-28 22:37 编辑

class Demo {
        public static void main(String[] ags) {
                Properties p = new Properties();
                p.put("1", "zhangsan");
                p.put("2", "zhangsan");
                p.put("3", "wangwu");
                Enumeration<?> keys = p.propertyNames();
                while (keys.hasMoreElements()) {
                        String key = (String) keys.nextElement();
                        System.out.println(key);
                }               
        }
}
class Properties extends Hashtable<Object, Object> {
        protected Properties defaults;

        public Enumeration<?> propertyNames() {
                Hashtable h = new Hashtable();
             //为什么注释掉enumerate(h)方法后, 就不能打印出结果???
                     enumerate(h);

                     return h.keys();
        }

        private synchronized void enumerate(Hashtable h) {
                if (defaults != null) {
                        defaults.enumerate(h);
                }
                for (Enumeration e = keys(); e.hasMoreElements();) {
                        String key =  (String)e.nextElement();
                        h.put(key, get(key));
                }
        }
}

6 个回复

倒序浏览
你这个好像改的是java的源码 。挺猛的
回复 使用道具 举报
你是在修改枚举的源码?
我们来一步步分析源码
1.先用put方法这个方法是hashtable的
2.你添加三个元素后 又启用了p.propertyNames();
3.这个propertyise中的propertyNames()方法调用enumerate(h); 但是在调用前又新建立了hashtable
也就是你把老hashtable中的对象放进的新的hashtable()类中  然后你返回新的h中的keys() 最终将其打印出来

我们再来说说为什么你屏蔽后 什么也打印不出来

答:因为你屏蔽以后 新的h什么也没有添加进去 ,你想打印什么东西呢?那个for循环根本不用去执行

不知道我这么说你明白没有?
其实也不明白你做这个是为了干啥子?
回复 使用道具 举报
本帖最后由 张权 于 2013-4-28 22:45 编辑
偏執旳、靑春 发表于 2013-4-28 21:19
你是在修改枚举的源码?
我们来一步步分析源码
1.先用put方法这个方法是hashtable的


哦, 明白了,谢谢啊,  唉!!
调用put方法是添加到 Entry 中,
但是, 在调用propertyNames()方法时, 内部new了一个新的Hashtable, 那么这个Hashtable 也有一个自己的Entry,这个Entry是没有值的, 然后通过调用enumerate方法, 把 老的Entry中的值, 放到新的Entry中去, 然后获取键, 再返回...
    还是代码看少了, 练少了, 这个本来我分析也是这么回事, 可是就上面说的没有想通, 没有考虑到新new的一个Hashtable对象, 有一个新的Entry,  接着又因为调用enumerate方法时, 里面的for循环 调用keys方法,获取所有键, 我又把它弄混了, 以为是调用的新Hashtable里面的Entry, 因为新的Entry根本就没有值,所以这样就矛盾了, 一直想不通, 其实是自己恰好搞反了,谢谢了啊! 这里我自己又简单的写了一个模拟代码:
//A类就相当是Hashtable类
class A {
        //StringBuilder就相当是Entry
        StringBuilder sb = new StringBuilder();
        
        public String put(String str) {
                sb.append(str);
                return sb.toString();
        }
        
        public String keys() {
                return sb.toString();
        }

}

//B类就相当是Properties类
class B extends A{
        public String propertyNames() {
                A a = new A();
                fun2(a);
                return a.keys();
        }
        
        public void fun2(A a) {
                a.sb.append(keys());
        }
}



回复 使用道具 举报
谭威 发表于 2013-4-28 19:23
你这个好像改的是java的源码 。挺猛的

.......................
要是猛就不会到论坛来问了
回复 使用道具 举报
本帖最后由 张权 于 2013-4-28 22:51 编辑
偏執旳、靑春 发表于 2013-4-28 21:19
你是在修改枚举的源码?
我们来一步步分析源码
1.先用put方法这个方法是hashtable的


关于你问我这是为什么这样做,是因为我下面的代码抛异常, 我就想查源码看看原因:
import java.util.Enumeration;
import java.util.Properties;

public class Demo {
        public static void main(String[] args) {
                Properties p = new Properties();
                p.put(1, "zhangsan");
                p.put(2, "zhangsan");
                p.put(3, "wangwu");
                Enumeration<?> keys = p.propertyNames();
                while (keys.hasMoreElements()) {
                        Integer key = (Integer) keys.nextElement();
                        System.out.println(key.toString());
                }
        }
}
至于这个原因, 其实源码已经很清楚了, 就是在遍历老值时, 把老值添加到新Hashtable对象的时候, 源码做了 一个强转动作 String key = (String)keys.nextElement();  也就是说在把老值添加到新的Hashtable中的值, 必须要满足能够强转成String类型, 而这样, 那么我传递的Integer类型的值是没有办法直接进行强转的.
回复 使用道具 举报
请版主过来加分啊!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马