【Effective Java】8、优先考虑类型安全的异构容器

有的时候我们一个容器只有一个类型或几个类型并不能满足我们的要求,比如set中存放的元素类型都是同一种,map也就指定的两种

这里我们可以将键进行参数化,而不是将容器参数化,也就是我们可以给容器传一个键的类型,然后value用来放对应的实例,这样就可以存放多个不同的类型了

如:

package cn.xf.cp.ch02.item29;

import java.util.HashMap;
import java.util.Map;

public class ManyTypeClass
{
    //一个存放数据的容器,由于键值类型是不确定的,那么值类型就只能是object类型
    private Map<Class<?>, Object> data = new HashMap<Class<?>, Object>();

    public <T> void putData(Class<T> type, T instance)
    {
        //吧数据放入进去
        if(type != null)
        {
            //这里需要进行一下类型转换,通过Class的cast方法,因为泛型是基于擦除的,如果不进行验证的话,那么插入的数据到底是不是真的type类型就无法确定的了
            data.put(type, type.cast(instance));
        }
    }

    public <T> T getDate(Class<T> type)
    {
        //取出数据,由于数据存放进去是object类型的,那么取出来的时候就需要进行一次类型转换
        return type.cast(data.get(type));
    }

    public static void main(String[] args)
    {
        ManyTypeClass mtc = new ManyTypeClass();
        mtc.putData(String.class, "cutter_point");
        mtc.putData(Integer.class, 0xcab145de);
        mtc.putData(Class.class, ManyTypeClass.class);
        mtc.putData(ManyTypeClass.class, mtc);

        String dataString = mtc.getDate(String.class);
        int dataInteger = mtc.getDate(Integer.class);
        Class<?> dataClass = mtc.getDate(Class.class);
        ManyTypeClass mtc1 = mtc.getDate(ManyTypeClass.class);

        System.out.printf("%s %x %s %s%n", dataString,
                dataInteger, dataClass.getName(), mtc1.getDate(String.class));
    }
}

运行显示结果:

异构成功,这个类可以存放各种不同的类型,但是注意不要放List<String>类型或List<Integer>类型,因为首先List<String>.class是不合法的,然后就算放个List进去,如果里面存放的不同的数据,key是List的,结果里面放的是List<Integer>类型,得到的结果并不能满意,也即是不能用在不可具体化的类型中。可以保存String或String[]但是如果是List<String>类型就无法编译了

时间: 2024-12-18 21:25:44

【Effective Java】8、优先考虑类型安全的异构容器的相关文章

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

集合API展示了泛型的一般用法.但是它们(Set,HashMap,Map)限制了每个容器只能有固定数目的类型参数. 比如Set集合,HashMap集合: import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class NormalUse { public static void main(String[] args) { Set<String>

第29条:优先考虑类型安全的异构容器

一个Set只有一个类型参数,表示它的元素类型,一个Map有两个类型参数,表示它的键和值类型. 但是有时候,需要更多的灵活性,如,数据库行有任意多的列,希望能以类型安全的方式访问所有的列.办法是将键进行参数化而不是将容器参数化,然后将参数化的键提交给容器,来插入或者获取值.用泛型系统来确保值的类型与它的键相符. 例子: public class Favorites { private Map<Class<?>, Object> favorites = new HashMap<C

Java 类型安全的异构容器

转载自:http://blog.csdn.net/sh_c1991/article/details/45965743 我们的想法是用key自身的class 类型作为key.因为Class 是参数化的类型,它可以确保我们使Context方法是类型安全的,而无需诉诸于一个未经检查的强制转换为T.这种形式的一个Class 对象称之为类型令牌(type token). [java] view plain copy public class Context { private final Map<Clas

类型安全的异构容器

原文:http://gafter.blogspot.com/2006/12/super-type-tokens.html 1. 泛型通常用于集合,如Set和Map等.这样的用法也就限制了每个容器只能有固定数目的类型参数,一般来说,这也确实是我们想要的. 然而有的时候我们需要更多的灵活性,如数据库可以用任意多的Column,如果能以类型安全的方式访问所有Columns就好了,幸运的是 有一种方法可以很容易的做到这一点,就是将key进行参数化,而不是将容器参数化,见以下代码 1 public cla

【电子书】Effective Java中文版下载

下载地址: 点击打开链接 (需要资源0分的联系我~) <Effective Java中文版(第2版)>主要内容:在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案.通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰.健壮和高效的代码.第2版反映了Java 5中最重要的变化,并删去了过时的内容. <Effective Java中文版(第2版)>中的每条规则都以简短.独立的小文章形式出现,并

Effective Java读后感

<Effective Java>读后感 1       创建和销毁对象 1.1    考虑用静态工厂方法代替构造器 静态工厂方法优点: 静态工厂方法与构造器(构造方法)不同的第一大优势在于,它们有名称.见名知意,突出区别. 静态工厂方法与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新对象. 静态工厂方法与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象. 静态工厂方法与构造器不同的第四大优势在于,在创建参数化类型实例的时候,它们使代码变得更加简洁. 例如:

《Effective Java(中文第二版)》【PDF】下载

<Effective Java(中文第二版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382186 Java(中文第二版)>[PDF]"  TITLE="<Effective Java(中文第二版)>[PDF]" /> 编辑推荐 <Sun 公司核心技术丛书:EffectiveJava中文版(第2版)>内容全面,结构清晰,讲解详细.可作为技术人员的参考用书.编码平添乐

《Effective Java》第5章 泛型

第23条:请不要在新代码中使用原生态类型 声明中具有一个或者多个类型参数( type parameter)的类或者接口,就是泛型(generic)类或者接口. 每种泛型定义一组参数化的类型(parameterized type),构成格式为: 先是类或者接口的名称,接着用尖括号(<>)把对应于泛型形式类型参数的实际类型参数列表括起来.例如,List 最后点,每个泛型都定义一个原生态类型[raw type],即不带任何实际类型参数的泛型名称.例如,List 如果使用原生态类型,就失掉了泛型在安全

Effective Java 读书笔记之四 泛型

泛型的本质是参数化类型.只对编译器有效. 一.请不要在新代码中使用原生态类型 1.泛型类和接口统称为泛型,有一个对应的原生态类型. 2.原生类型的存在是为了移植兼容性. 3.无限制通配类型和原生态类型的区别是:通配符类型是安全的,原生态类型不安全.你可以将任何元素放入到原生态类型的集合中,但不能将除了null之外的其他任何元素放到Collection<?>中. 4.两条例外: a.在Class中只能使用原生态类型,因为泛型信息可以在运行时被擦除. b.在操作instanceof时,使用参数化类