首页 > 编程语言 > 详细

Java泛型

时间:2020-01-16 20:05:28      阅读:67      评论:0      收藏:0      [点我收藏+]

一.泛型的概述

? 泛型是java 1.5的新特性,本质是参数化类型,就是将要操作的数据类型指定为一个参数。泛型可以使用在类,接口,方法中,分别叫做泛型类,泛型接口以及泛型方法。

? 比如ArrayList<String> list = new ArrayList<>()就是一个泛型类。

? 为什么要使用泛型?

? 在没有泛型之前,将数据存入集合,是这样子操作的:

public class GenericTest {
    public static void main(String[] args) {
        ArrayList array = new ArrayList();

        array.add("Hello");
        array.add(123);

        String str = (String)array.get(0);
        int num = (int)array.get(1);

        System.out.println(str);
        System.out.println(num);
    }
}

? 存入数据的时候是可以任意类型,取出来时需要做一个类型转换,这样子操作就存在一个问题,过了许久后可能会忘记了集合的第几个数据是什么类型,一旦搞错,就会产生一个异常java.lang.ClassCastException

? 引入泛型之后,代码就变成了这样子的:

public class GenericTest {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList();

        array.add("Hello");
        // array.add(123);

        String str = array.get(0);
        // int num = (int)array.get(1);

        System.out.println(str);
        // System.out.println(num);
    }
}

? 在编译时就已经确定了参数类型为String,如果存入集合的数据不是String,在编译时就会报错,在取出数据时也不需要进行类型转换了,这样一来,使得在运行时可能发生的java.lang.ClassCastException异常在编译时期就能被编译器发现,从而从运行时错误变成了编译时期的错误,并且在使用的时候避免了类型转换的麻烦。

二.泛型的定义

  1. 定义泛型类的格式

    修饰符 class 类名<代表泛型的变量> { ... }

    比如源码中的ArrayList的定义是这样的:

    public class ArrayList<E> extends AbstractList<E>
    
    ?    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    
    {
     ....
    }

    泛型类的编写比普通类要稍微复杂一些,我们可以根据普通类的编写来进行改造从而完成泛型类的编写。

    比如先创建一个普通类Person

    public class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    }

    然后使用T来标记需要指定的类型,这里是String,改写后的Person类如下:

    public class Person<T> {
        private T name;
    
        public Person(T name) {
            this.name = name;
        }
    
        public T getName() {
            return this.name;
        }
    }
  2. 定义泛型方法的格式

    修饰符 <代表泛型的变量> 返回值类型 方法名(参数) { ... }

    比如可以在普通类中定义泛型方法:

    public class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        public <T> void print (T msg) {
            System.out.println(msg.getClass());
        }
    }
  3. 定义泛型接口的格式

    修饰符 interface 接口名<代表泛型的变量> { ... }

    比如:

    public interface List<E> {
        ....
    }
  4. 泛型类、泛型方法和泛型接口的确定时间

    上面介绍了如何定义泛型,但是这个泛型在什么时候确定泛型类型呢?

    对于泛型类,是在创建对象时候确定泛型类型的,比如:`ArrayList<String> list = new ArrayList<>()

    对于泛型方法,是在方法被调用的时候确定泛型类型的,比如Person p = new Person(); p.print("hello java");

    对于泛型接口,是有两种情况存在的:

    第一种:在实现接口时候指定泛型类型。

    第二种:如果实现接口的时候仍旧使用了泛型,则在创建接口实现类对象时候指定泛型类型。

  5. 泛型的定义需要注意的几点

    • 泛型的类型只能是引用类型,不可以是基本类型

    • <代表泛型的变量> 尖括号里可以使用任意的字母,对编译器来说都是一样的,但是习惯上使用T,E,K,V等字母来表示(完全是因为程序员习惯)

      其中主要是因为这些字母都代表了一个含义:

      • T :Type(类型)
      • E:Element(元素)
      • K:Key(键)
      • V:Value(值)

三.泛型的通配符

? 泛型有三种类型的通配符:

  • <? extends T>:上边界通配符

    意义:表示只能接受T类型或者T类型的子类型

    缺陷:只能读取对象,不能添加任何对象(null除外)

  • <? super T>:下边界通配符

    意义:表示只能接受T类型或者T类型的父类型

    缺陷:只能添加对象,不能读取对象(Object除外)

  • <?>:无界通配符

    等同于:<? extends Object>

比如有Object类,String类,Number类,Integer类,其中Number类是Integer类的父类

// 泛型的上边界,此时泛型?,必须是Number或者其子类
public static void getElement1(Collection<? extends Number> c) {}
// 泛型的下边界,此时泛型?,必须是Number或者其父类
public static void getElement2(Collection<? super Number> c) {}

public static void main(String[] args) {
    Collection<Integer> list1 = new ArrayList<Integer>();
    Collection<String> list2 = new ArrayList<String>();
    Collection<Number> list3 = new ArrayList<Number>();
    Collection<Object> list4 = new ArrayList<Object>();
    
    getElement1(list1); 
    getElement1(list2); // error
    getElement1(list3);
    getElement1(list4); // error
    
    getElement2(list1); // error
    getElement2(list2); // error
    getElement2(list3);
    getElement2(list4);
}

Java泛型

原文:https://www.cnblogs.com/LucasBlog/p/12202992.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!