楼主: superloafer

[精华] 请教一下:使用了未经检查或不安全的操作

[复制链接]
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
11#
发表于 2007-1-23 05:46 | 只看该作者
先说第一个错误,符号"〈"和"〉"之间的标志符称为类型参数,不一定是世纪类型,一般使用单个大写字母,E一般表示Element,T表示Type。所以使用String就会把java.lang.String给覆盖了,这是对泛型类声明上的概念不清晰。

generictest1.jpg (25.04 KB, 下载次数: 129)

generictest1.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
12#
发表于 2007-1-23 05:53 | 只看该作者
第二,声明一个泛型类,其父类也是泛型类,则要将同样的类型参数赋给父类,所以没有给ArrayList指定"String"是导致另外错误的原因。
正确的是这样的,
static class CustomArrayList1<String> extends ArrayList<String> {
                public void method() {
                        String s = null;
                        this.add(s);
                        // this.add(2);
                        this.add(s);
                }
               
                public void method(String s) {                       
                        this.add(s);
                }
}

注意反编译后的代码是
static class GenericTest1$CustomArrayList1 extends ArrayList
{

    public void method()
    {
        Object s = null;
        add(s);
        add(s);
    }

    public void method(Object s)
    {
        add(s);
    }

    public void display()
    {
        for(int i = 0; i < size(); i++)
            System.out.println((new StringBuilder(" ").append(get(i)).toString());

    }
}

注意粗体部分的Object和toString()的调用。声明的所谓String,最后变为普通的Object。

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
13#
发表于 2007-1-23 05:59 | 只看该作者
如果强制使用java.lang.String,就会出现如下错误,类型参数和静态指定类型的参数发生冲突。导致无法编译。

generictest2.jpg (11.55 KB, 下载次数: 134)

generictest2.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
14#
发表于 2007-1-23 06:08 | 只看该作者
而如果将java.lang.String再次强制转换为名为“String”的类型参数,就可以编译,告警则为运行时可能发生的类型强制转换错误。

generictest3.jpg (30.58 KB, 下载次数: 108)

generictest3.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
15#
发表于 2007-1-23 06:09 | 只看该作者
从反编译后的代码即可看出method和method1的区别。

generictest4.jpg (10.09 KB, 下载次数: 128)

generictest4.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
16#
发表于 2007-1-23 06:15 | 只看该作者
可以看出this.add()的效果和ArrayList list = new ArrayList(); list.add()的效果一样,因为其本身就使用继承自ArrayList的方法,并未添加任何和范型相关的内容,在1.5中,自然会有一条警告。我将 ArrayList<Object>作为父类,警告消失,这次调用this.add()就会检查传入参数是否是一Object对象, String对象是Object的子类,所以编译不会报错。[/COLOR] 我试了一下改为ArrayList<String>,结果出错了,范型这东东还得看看,没彻底搞明白。


不报错不是因为String是Object的子类,是因为任何类型参数将来所实际实例化的类都是Object的子类。


如图,没有任何报警。

generictest5.jpg (16.53 KB, 下载次数: 123)

generictest5.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
17#
发表于 2007-1-23 06:24 | 只看该作者
感觉就是CustomArrayList1<String>继承的ArrayList<String>根本就和原来的ArrayList不同了,所以才说找不到add()方法了。看来对这个机制还是云里雾里的。这到底是怎么回事啊。


在声明语法正确以后,出现的问题就很明显了,因为确实没有定义add(java.lang.String)的方法,呵呵,解决办法就是强制转换为参数化类型。this.add((String)"ddd";

generictest6.jpg (20.51 KB, 下载次数: 132)

generictest6.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
18#
发表于 2007-1-23 06:34 | 只看该作者
10楼中
class A
{
{
System.out.println("This is class A";
}
}

class B extends A
{
{
System.out.println("This is class B";
}
}

class CustomArrayList1<A> extends ArrayList<B>{

public void method() {
this.add(new B());
this.add(new B());
}

此A非彼A,这和前面的String问题是一样的。实际应用中,如果为了限制类型参数的类,一般使用extends语法。

如下,才算声明了一个真正的泛型类,同时限制了其所能容纳的类型必须是A的子类。

generictest7.jpg (39.35 KB, 下载次数: 113)

generictest7.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
19#
发表于 2007-1-23 06:37 | 只看该作者
这个时候如果声明非A子类的类型就会出错了。

generictest8.jpg (57.01 KB, 下载次数: 110)

generictest8.jpg

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
20#
发表于 2007-1-23 06:45 | 只看该作者
最后,附上一个简化的List的实现,其实不见得非用ArrayList或者List不可,呵呵
[php]
        // generic Liste
        public class Liste<E> {
                Element<E> kopf, fuss;

                public Liste() {
                        kopf = fuss = null;
                }

                public void add(E e) {
                        if (kopf == null) {
                                kopf = fuss = new Element<E>(e);
                        } else {
                                fuss = fuss.nf = new Element<E>(e);
                        }
                }

                public synchronized boolean contains(E e) {
                        boolean ergebniss = false;
                        Element<E> ele = kopf;
                        while (ele != null) {
                                // vereinfacht !
                                if (ele.value == e || ele.value.equals(e)) {
                                        ergebniss = true;
                                        break;
                                } else {
                                        ele = ele.nf;
                                }
                        }
                        return ergebniss;
                }

                public synchronized void remove(E e) {
                        if (kopf != null) {
                                if (kopf.value == e || kopf.value.equals(e)) {
                                        if (kopf == fuss) {
                                                kopf = fuss = null;
                                        } else {
                                                kopf = kopf.nf;
                                        }
                                } else {

                                        remove(kopf, kopf.nf, e);
                                }
                        }
                }

                private synchronized void remove(Element<E> fg, Element<E> ele, E e) {
                        if (ele != null) {
                                if (ele.value == e || ele.value.equals(e)) {
                                        fg.nf = ele.nf;
                                        ele.nf = null;
                                        if (ele == fuss) {
                                                fuss = fg;
                                        }
                                } else {
                                        remove(ele, ele.nf, e);
                                }
                        }
                }

                public synchronized E such(E e) {
                        Element<E> ele = kopf;
                        E ergebniss = null;
                        while (ele != null) {
                                if (ele.value == e || ele.value.equals(e)) {
                                        ergebniss = ele.value;
                                        break;
                                } else {
                                        ele = ele.nf;
                                }
                        }
                        return ergebniss;
                }
        }

        // generic Element
        public class Element<E> {
                E value;

                Element<E> nf;

                public Element(E value) {
                        this.value = value;
                }

                public Element(E value, Element<E> nf) {
                        this.value = value;
                        this.nf = nf;
                }
        }
[/php]

PS:个别单词非英语,不过不影响阅读,呵呵

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表