西安老挝赌场网-聊聊 JAVA 泛型基础Web前端培训,ioses培训,androids培训,JavaEE培训,Python培训,软件测试

西安老挝赌场-专注强师高品质课程,只培养拿高薪的实战型IT精英!

关于老挝赌场 加入收藏

西安老挝赌场

咨询热线:18066525703

▶ 您现在的位置:首页 > 行业动态 > 聊聊 JAVA 泛型基础

聊聊 JAVA 泛型基础

时间:2018-01-30 09:23:20    作者:西安老挝赌场 324

先看下面一个例子,test1实例化一个List容器的时候没有指定泛型参数,那么老挝赌场可以往这个容器里面放入任何类型的对象,这样是不是很爽?但是当老挝赌场从容器中取出容器中的对象的时候老挝赌场必须小心翼翼,因为容器中的对象具有运行时的类型信息,这意味着你不能够将一个带有运行时类型信息的对象赋值给另一个类型,否则ClassCastException。


public void test1() throws Exception {

    List list = new ArrayList();

    list.add("float.lu");

    list.add(1);

    String name = (String) list.get(0);

    int num = (Integer) list.get(1);

    System.out.println(String.format("name[%s], num[%s]", name, num));

}

上面的代码没问题,可以很好地编译和运行通过,问题是我必须要事先很清楚地知道容器中的索引为0的对象是什么类型,索引为1的对象是什么类型,很显然,这在实际应用中是不切实际的,也是一种很不靠谱的做法,那么这个问题如何解决呢?泛型。


引入泛型


为了解决这个问题,老挝赌场引入泛型,下面代码可以看出与上面不同的是老挝赌场在实例化容器的时候加了这个东西,这个东西的学名叫做泛型参数,就像普通方法带有参数一样,interface List中的E为形式参数、而String为实参。


public void test2() throws Exception {

    Listlist = new ArrayList();

    list.add("a");

    list.add(1)//1

}

引入泛型后,老挝赌场规定这个容器中只能存放类型为字符串类型的对象,好的,编译器可以识别泛型并帮老挝赌场检查编译错误,上面的代码中1处会出现编译错误。注意:泛型信息仅仅存在于编译期间,编译器可以通过泛型信息来对代码是否存在违规行为(编译错误)来进行检查,当编译器将代码编译为字节码之后,泛型信息将不复存在,然而对象的运行时信息仍然是有的,这就解释了为什么会出现ClassCastException。


别高兴太早


有了泛型老挝赌场可以让代码安全地通过编译,并且老挝赌场认为他是安全的了,嘿嘿,是否就真的安全了呢?是否就能和ClassCastException说拜拜了呢?答案是:NO。看看下面这段代码:


public void test3() throws Exception {

    Listlist = new ArrayList();

    list.add("a");

    list.add("b");

 

    List _list = list;

    ListintegerList = _list;

    for (Integer item : integerList) {

        System.out.println(String.format("item[%s]", item));

    }

}

上面这段代码编译没有问题,老挝赌场没有直接将泛型参数为String的容器赋值给泛型参数为Integer的容器,而是花了点点小心思,老挝赌场现将list赋值给_list,_list生命为可以存储任何类型,也就相当于无特定类型,而后老挝赌场又把_list赋值给integerList容器,integerList容器被声明为只能存储类型为Integer的对象。悲催的是这段代码在运行的时候报了ClassCastException,很明显,老挝赌场知道在迭代integerList容器中的对象的时候,这些对象是有运行时类型信息的,当带有String类型信息的对象赋值给Integer的时候显然就报错了。这一切看起来似乎没问题,符合逻辑,但是有一个问题老挝赌场还没有问:为什么会没有编译错误?


泛型术语


在学习数学的时候老挝赌场往往会对一个证明题进行论证,而论证之前老挝赌场手上往往会有一些不需要证明的已知定理,下面这些“定理”将被用来直接回答上一节中遗留的问题。


List被称作泛型类型。

List中的E被称为类型变量或类型参数。

List被称为参数化类型。

List中的String被称为实际类型参数。

List中的<>年typeof。

List被称为原始类型。

参数化类型可以引用一个原始类型对象,编译报告警告。

原始类型可以引用一个参数化类型对象,编译报告警告。

由上可知,ListintegerList = _list;可以通过编译。


看清本质


经过上面的一些小波折,老挝赌场了解一些关于泛型的本质:泛型是给javac编译器使用的,javac是JAVA的编译器,而泛型可以让代码在编译期间确定类型安全,比如老挝赌场告诉编译器某个容器只能存储某种类型的对象,那么编译器会为老挝赌场好好地检查,确保类型安全,但是安全是相对的,只要老挝赌场逃过编译器,老挝赌场就有一百种方法让代码ClassCastException(比如反射)。同时编译之后参数化类型在运行时没有任何泛型信息,也就是为什么List.class和List.class是同一个东西。除了参数化类型之外,容器中的对象在运行的时候是有类型信息的,也就是为什么会ClassCastExcetion。关于泛型还有很多内容,这里不做多讲,文中有误也欢迎留言讨论。


为学日益,为道日损,损之又损,以至于无为。无为而无不为,取天下常事以无事;及其有事,不足以取天下。

开班信息



西安总部

18066525703

学科:HTML5培训、UI交互设计培训、Java+云数据培训、Linux云计算培训、androids培训、ioses培训
地址:西安市雁塔区长安南路86号长丰国际广场A座22楼(电视塔西公交站下车)

西安中心

18066525703

学科:HTML5培训、UI交互设计培训、Java+云数据培训、Linux云计算培训、androids培训、ioses培训
地址:西安市雁塔区长安南路86号长丰国际广场A座22楼(电视塔西公交站下车)

官方微信

手机官网

©2017-2018陕西华建人力资源有限公司版权所有 陕ICP备17010039号-1