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.

  • 相关阅读:
    VS2010 error LNK2019: 无法解析的外部符号
    strspn()函数的使用方法
    直接插入排序
    opecv 常用的函数
    matlab中 fprintf 和disp的用法
    面试经历
    挚爱 泰戈尔
    见与不见
    无题
    Cannot create PoolableConnectionFactory (Could not create connection to database server.
  • 原文地址:https://www.cnblogs.com/lucare/p/9312649.html
Copyright © 2011-2022 走看看