zoukankan      html  css  js  c++  java
  • 再看泛型

    基本介绍

    泛型实现了参数化类型的概念,使代码可以应用于多种类型。泛型的出现最引人注目的一个原因,就是为了创造容器类。它的主要目的就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性。

    泛型模式推荐名称

    K – 键,比如映射的键。

    V – 值,比如 List 和 Set 的内容,或者 Map 中的值。

    E – 异常类。

    T – 泛型。

    为什么要使用泛型:
    1. 编译期安全检查,防患于未然。
    2. 从集合中取元素不需要进行手工转换,编译器会替你插入隐式的转换。
    3. 参数化类型,让类的使用更加灵活。

    注意:
    虽然你可以将List < String > 传递给类型List的参数,但是不能将它传给类型List< Object >的参数。泛型有子类型化的规则,List< String >是原生态类型List的一个子类型,而不是参数化类型List< Object >的子类型。

    几种写法

    • 原生态类型 如 List。 移植兼容性 促成了支持原生态类型的决定
    • List< Object>是个参数化类型,表示可以包含任何对象类型的一个集合
    • 无限制通配符类型如List< ?> 读作‘某个类型的集合’
    • 类型限制< T extends Comparable< T>> 读作‘针对可以与自身进行比较的每个类型T’
    • 有限制的通配符类型< ? extends E>和< ? super E>

    泛型方法

    一个基本的原则是:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛化,那么应该有限采用泛型方法。下面来看一个简单的泛型方法的定义:

    public class Main {
    
        public static <T> void out(T t) {
            System.out.println(t);
        }
    
        public static void main(String[] args) {
            out("findingsea");
            out(123);
            out(11.11);
            out(true);
        }
    }

      
    使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
      
    需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。

    类型推导

    泛型方法的一个显著特征是,无需明确指定类型参数的值,不像调用泛型构造器的时候是必须指定的。编译器通过检查方法参数的类型来计算类型参数的值。

    利用泛型方法调用所提供的类型推导,使创建参数化类型实例的过程变得更加轻松。

    public static <K,V> HashMap<K,V> newHashMap(){
        return new HashMap<K,V>();
    }

    可以用下面的简介代码来取代重复的声明:

    Map<String,List<String>> anagrams = newHashMap();

    类型擦除

    public class GenericTest {
    
        public static void main(String[] args) {
            Class c1 = new ArrayList<String>().getClass();
            Class c2 = new ArrayList<Integer>().getClass();
            System.out.println(c1 == c2);//true
        }
    }

    ArrayList< String>和ArrayList< Integer>很容易被认为是不同的类型。但上面的程序会认为它们是相同的类型。

    在泛型代码内部,无法获得任何有关泛型参数类型的信息。

    Java泛型是使用擦除来实现的,这意味着在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此ArrayList< String>和ArrayList< Integer>在运行时事实上是相同的类型。这两种形式都被擦除成它们的“原生”类型 – List。

    边界

    边界使得你可以在用于泛型的类型参数上设置限制条件,但是其潜在的重要的效果是你可以按照自己的边界类型来调用方法。这点在使用框架的时候,设计的模板类中应用较多。

    public class ServiceImpl<M extends BaseMapper<T,I>, T, I> implements BaseService<T,I>{
    
        @Autowired
        protected M baseMapper;
    
        public int insert(T t) {
            return baseMapper.insert(t);
        }
    
        public int deleteById(I id) {
            return baseMapper.deleteById(id);
        }
    
        public int update(T t) {
            return baseMapper.update(t);
        }
    
        public T selectById(I id) {
            return baseMapper.selectById(id);
        }
    
        public List<T> selectList() {
            return baseMapper.selectList();
        }
    }

    有了这个边界之后,可以调用边界类型里面定义的方法。

    PECS

    Producer Extends Consumer Super:
    频繁往外读取内容的,相当于生产者,适合用上界Extends.
    经常往里插入的,相当于消费者,适合用下界Super.

  • 相关阅读:
    SDUT 2143 图结构练习——最短路径 SPFA模板,方便以后用。。 Anti
    SDUT ACM 1002 Biorhythms 中国剩余定理 Anti
    nyist OJ 119 士兵杀敌(三) RMQ问题 Anti
    SDUT ACM 2157 Greatest Number Anti
    SDUT ACM 2622 最短路径 二维SPFA启蒙题。。 Anti
    二叉索引树 区间信息的维护与查询 Anti
    SDUT ACM 2600 子节点计数 Anti
    UVA 1428 Ping pong 二叉索引树标准用法 Anti
    2010圣诞Google首页效果
    Object
  • 原文地址:https://www.cnblogs.com/lucare/p/9312649.html
Copyright © 2011-2022 走看看