文档章节

关于泛型

stephen_wu
 stephen_wu
发布于 2016/08/29 14:44
字数 1054
阅读 41
收藏 1

一直有用到泛型,但是没有深入研究其用法,今天遇到一个方法就有点蒙圈,如下:

public <T extends TransactionBaseService> int aroundTransHelper(T service, Map<String, Object> params, Map<String, Object> container)
        throws Exception {

return 0;

}

后来理解为<T extends TransactionBaseService>是定义后面的泛型参数(若理解错了,再来改正).

详细的定义和引用见:http://my.oschina.net/jiemachina/blog/201507

还有看到的一篇不错的blog引用如下:

泛型机制常用的参数有3个:
“?”代表任意类型。如果只指定了<?>,而没有extends,则默认是允许任意类。
extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类。
super关键字声明了类型的下界,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object
前提
Fruit是Apple和Orange的超类。
本章通过java代码逐一分析泛型参数的意义和区别
extends参数:
[java]  
public void extend(List<? extends Fruit> list, Fruit fruit){    
        Fruit now = list.get(0);    
        System.out.println("now==>" + now);  
    //    Apple a = list.get(0);  无法通过编译  
        Object o = list.get(0);   
        System.out.println(o);  
        // list.add(fruit); //这句话无法编译      
        // list.add(new Object());  // 无法通过编译  
        list.add(null);//这句可以编译,因为null没有类型信息    
    }   
在上面的例子中,可以明确从list中取得的记录一定是Fruit,但是无法确定是Apple,list除了传入null外,不能添加其他任何参数;分析原因前先看以下的例子:
[java] 
public void testExtendType(){  
    List<? extends Fruit> list = new ArrayList<Fruit>();  
    List<? extends Fruit> list2 = new ArrayList<Apple>();  
    List<? extends Fruit> list3 = new ArrayList<Orange>();  
    extend(list2, new Apple());  
}  
从以上代码可以看出:
extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类,List<? extends Fruit> 可以指向 ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>()等。现在如果传入的参数list为new ArrayList<Apple>(),则此时你向此list中添加
Fruit,则肯定报错。而读取数据时,不管list是什么类型,读取的数据肯定都是Fruit,同时Fruit也是Object。
通过以上的分析,知道直接往继承extends中的列表中添加记录是不行的,那么如何向extends修饰的list中添加记录,可以使用泛型方法来达到目的:
[java]  
public <T extends Fruit> void extendType2(List<T> list, T date){    
        list.add(date);    
    }   
调用示例如下:
[java]  
public void testExtendType2(){    
        List<Apple> list = new ArrayList<Apple>();    
        extendType2(list,new Apple());    
    }  
super参数
super用的不多,只简单介绍一下。
[java]  
public void superType(List<? super Apple> list, Apple apple){    
        Object o = list.get(0);  
        System.out.println(o);  
    //  Apple a = list.get(0); // 不能编译  
          
     // Apple apple = list.get(0); // 不能编译    
        list.add(apple);  
//      list.add( new Object());  // 不能编译  
//      list.add( new Fruit());  // 不能编译  
    }    
在以上代码中,从list中读取的记录无法确定是任何类型(除Object),list除了添加Apple外,不能添加任何类型的对象(包括Object)。分析原因前先看以下代码:
[java]  
public void testSuperType(){    
    List<? super Apple> list = new ArrayList<Apple>();    
    List<? super Apple> list2 = new ArrayList<Fruit>();   
    superType(list2, new Apple());    
}  
super关键字声明了类型的下界,表示参数化的类型是所指定的类型,或者是此类型的父类型,直至Object。List<? super Apple > 可以引用  List<Apple>,也可以引用 List<Fruit>,所以无法保证list中都是Apple,但是可以保证,所有list引用的都是Apple的父类,所有向此列表中添加Apple是没有问题的,而很显然你向List<Fruit>、List<Apple>中添加Object、Fruit对象,肯定失败,只能够添加Apple。
?参数
“?”代表任意类型。?可以看做 ? extends Object 的缩写。
[java] 
public void wideCardType(List<?> list, Fruit fruit ){  
    Object o = list.get(0);  
    System.out.println(list.get(0));  
    //  list.add(fruit);  // 不能编译  
    //  list.add(new Object()); // 不能被编译  
}  
[java]  
public void testWideCardType(){  
        /** 
         * ? 可以看做 ? extends Object 的简化版 
         */  
        List<?> list = new ArrayList<Fruit>();  
        List<?> list2 = new ArrayList<Apple>();  
        List<?> list3 = new ArrayList<Object>();  
          
        wideCardType(list,new Fruit());  
    }  
List<? super Object> 可以引用  List<任何类型>,而Object是所有的对象的祖先,此list只能添加Object类型对象。
extends和super意义记忆的技巧
? extends A: ?继承A,?是A的子类,或者?是A本身
? super B:    ?是B的父类,或者?是B本身

本文转载自:

stephen_wu
粉丝 1
博文 82
码字总数 22670
作品 0
虹口
程序员
私信 提问

暂无文章

spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库

先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线,取出物料生产Bean 本文研究spr...

星星之焱
25分钟前
5
0
彻底解决tomcat乱码问题

本地项目请求访问,浏览器中文输出没问题。 部署到服务器上面之后,返回到浏览器的中文就乱码了。 尝试办法: 1.修改tomcat下的conf中的service.xml中的配置信息: 重新启动后,没有效果还是...

诗书易经
41分钟前
5
0
Java开发需要掌握的IDEA插件大全

1、Lombok 解释:这是最基本的插件,2017年就火了,还没用的百度一下吧。 博客链接:Intellij IDEA 安装lombok及使用详解 2、PlantUML integration 解释:各种类之间的关联图,高级开发必备。...

木九天
42分钟前
6
0
python学习10.05:Python range()快速初始化数字列表

实际场景中,经常需要存储一组数字。例如在游戏中,需要跟踪每个角色的位置,还可能需要跟踪玩家的几个最高得分。在数据可视化中,处理的几乎都是由数字(如温度、距离、人口数量、经度和纬度...

太空堡垒185
49分钟前
4
0
java单元测试,PowerMockito模拟方法内new对象

在做单元测试中有时候需要对方法内new出来的对象进行隔离,这是我们需要使用PowerMockito。 添加依赖 <dependency> <groupId>org.powermock</groupId> <artifactId>......

如梦之猿
50分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部