优雅编程之这样使用泛型,你就“正常”了(三十三)

开心一笑

【女:“一天中最幸福的时刻就是下班后你骑自行车载着我到街角那边吃卤肉饭。”
男:“说实话。”
女:“你骑自行车载我去吃卤肉饭。”
男:“说实话。”
女:“卤肉饭……”】

**提出问题******

java开发中如何更好使用范型???

解决问题

励志图片

以下来自《Effective Java》读书笔记:

请不要在新代码中使用原生态类型

参考高手文章:

http://www.cnblogs.com/nayitian/archive/2013/08/08/3245496.html

http://www.cnblogs.com/TwoWaterLee/p/5878056.html

参数化类型,通配符类型和原生态类型对比:

  • Set<Object>是个参数化类型,表示可以包含任何对象的一个集合;
  • Set<?>则是一个通配符类型,表示只能包含某种未知对象类型的一个集合;
  • Set则是个原生态类型,它脱离了泛型系统。**前两种是安全的,最后一种不安全。

无限制通配类型和原生态类型的区别是:通配符类型是安全的,原生态类型不安全。你可以将任何元素放入到原生态类型的集合中,但不能将除了null之外的其他任何元素放到Collection<?>中。

例如:

public static void main(String[] args) {
    List<String> strings = new ArrayList<>();
    unsafeAdd(strings, new Integer(42));
    String s = strings.get(0); // Compiler-generated cast
}
//重点在这里。list参数是原生态类型,整个编译过程都不会出现问题,但是运行时候就是会报ClassCastException异常
private static void unsafeAdd(List list, Object o) {
    list.add(o);
}

两条例外:

  • a.在Class中只能使用原生态类型,因为泛型信息可以在运行时被擦除。
  • b.在操作instanceof时,使用参数化类型非法。
消除非受检警告

参考高手文章:
http://blog.csdn.net/lqadam/article/details/52563155

要尽可能地消除每一个非受检的警告。

使用@SuppressWarnings("unchecked")注解,需要注意的是将该注解用在尽可能小的范围内,能在变量上使用的不在方法上使用,能在方法上使用的不在类上使用。

使用@SuppressWarnings注解时,都要添加一条注释,说明为什么这么做是类型安全的

列表优先于数组

下面的代码片段是合法的,却是不符合预期:

// 运行时候失败
Object[] objectArray = new Long[1];
objectArray[0] = “I don’t fit in”; // Throws ArrayStoreException

但下面这段代码则不合法,但却提醒了你怎样才能达到预期:

// Won’t compile!
List<Object> o1 = new ArrayList<Long>(); // Incompatible types
o1.add(“I don’t fit in”);

明显,利用列表可以在编译时发现错误。我们当然希望在编译时发现错误了。

总结:数组是协变的,数组是具体化的:在运行时才知道并检查它们的元素类型约束

优先考虑泛型,优先考虑范型方法

定义泛型方法语法格式如下:

http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html

引用高手的图片

参考高手文章:

http://www.cnblogs.com/cutter-point/p/5883279.html

修改前:

//这里使用原生类型是不合理的
 public static Set union1(Set s1, Set s2){
    Set result = new HashSet(s1);
    result.addAll(s2);
    return result;
}

修改后:

 //这里的范型没有安全警告
 public static <E> Set<E> union(Set<E> s1, Set<E> s2){
    Set<E> result = new HashSet<E>(s1);
    result.addAll(s2);
    return result;
}
利用有限制通配符来提升API的灵活性

参考高手文章:

http://www.cnblogs.com/13jhzeng/p/5726511.html

先看下面例子:

修改之前:

public void pushAll(Iterable<E> src) {  
    for (E e : src) {  
        push(e)  
    }  
}  

修改之后:

//src是生成者,所以使用extend
public void pushAll(Iterable<? extends E> src) {  
    for (E e : src) {  
        push(e)  
    }      
}      

pushAll的输入参数类型不应该为"E的Iterable接口",而应该为"E的某个子类型的Iterable接口",有一个通配符类型正符全此意:Iterable<? Extends E>

PECS 表示:producer-extends, consumer-super

如果参数化类型表示一个T生产者,就使用<? extends T>;如果它表示一个T消费者,就使用<? super T>。如果使用得当,通配符类型对于类的用户来说几乎是无形的。它们使方法能够接受它们应该接受的参数,并拒绝那些应该拒绝的参数。如果类的用户必须考虑通配符类型,类的API也许就会出错。

假设添加一个popAll方法,从堆栈中弹出每个元素,添加到指定集合中:

修改前

public void popAll(Collection<E> dst) {
    while(!isEmpty) {
        dst.add(pop());
    }
}

与未修改的putAll一样,应当允许类型为Number的栈帧放在包括Number在内的父类型中。所以,修改为:

修改后

public void popAll(Collection<? super E> dst) {
    while(!isEmpty) {
        //这里dst是消费者,所以使用super
        dst.add(pop());
    }
}

总之,如果参数化类型表示一个T生产者,就使用<? extends T>,如果表示一个T的消费者,就使用<? super T>

优先考虑类型安全的异构容器

参考高手文章:

http://blog.csdn.net/zhang_amao/article/details/52107612

http://blog.csdn.net/tkd03072010/article/details/7722110

public Class Favorites{

    public <T> void putFavorite(Class<T> type, T instance);
    public <T> T getFavorites(Class<T> type);
}

Favorites实例是类型安全的:当你向它请求String的时候,不会返回一个Integer给你。同时它也是异构的:不像普通的map,它的所有的键都是不同类型的。因此,我们将Favorites称作类型安全的异构容器

Map不能保证键和值之间的类型关系,即不能保证每个值的类型都与键的类型相同,当你考虑到这个问题时,可以尝试使用类型安全的异构容器:

public class Favorites {
    private Map<Class<?>, Object> favorites =
            new HashMap<Class<?>, Object>();
    
    public <T> void putFavorites(Class<T> type, T instance) {
        if(type == null)
            throw new NullPointerException();
        favorites.put(type, type.cast(instance));
    }
    
    public <T> T getFavorites(Class<T> type) {
        return type.cast(favorites.get(type));
    }
}

读书感悟

来自三毛《稻草人手记》

  • 我们还年轻,长长的人生可以受一点风浪。
  • 我喜欢看见幸福的人,不管他们结不结婚。
  • 快回来吧!我希望把有生之年都静静地跟你分享。短短的人生我们不要再分开了啊。
  • 肉体的软弱是一时的 精神的胜利是永久的
  • 自由是多么可贵的事,心灵的自由更是我们要牢牢把握住的;不然,有了爱情仍是不够的。

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,211评论 9 118
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,975评论 6 13
  • 泛型为集合提供了编译时类型检查。 23、不要在代码中使用原生态类型 声明中具有一个或多个类型参数的类或接口统称为泛...
    Alent阅读 924评论 6 2
  • 岁月,给我们定格在信师八九级美术班里 那里,有我们抹不去的共同记忆 同窗共读播撒下今生的友谊 我们的亲情胜似姐妹兄...
    居高不易张阅读 883评论 0 2