Java

泛型基础一

2020-04-22  本文已影响0人  静享时光

为什么使用泛型?

泛型可以提供一种强大的类型检查,是问题暴露在编译时期,使问题更容易发现与解决。

泛型是在接口,类和方法定义时,使接口和类称为一种参数,叫做类型参数,就像方法声明中使用的形式参数一样,只不过方法传递的形参是值,而泛型传递的是类型。

使用泛型的好处:

1、提供一种强大的类型检查,是问题暴露在编译时期。
2、消除转换

/**
 * 不使用泛型
 */
List dataList1 = new ArrayList();
//添加数据
dataList1.add("aaaa");
dataList1.add(131);
//获取数据,因为不添加泛型,List集合中可以传递任何类型的数据,
// 所以在获取的时候获取到的就是Object类型的数据,
Object o = dataList1.get(0);
// 因此在使用时必须进行强制类型转换。
String data = (String) o;

/**
 * 使用泛型
 */
List<String> dataList2 = new ArrayList<>();
//添加数据
dataList2.add("aaaa");
dataList2.add("123");
//获取数据,因为使用了泛型,所以在获取的时候就直接获取到的是设定好的类型,不需要进行强制类型转换。
String data2 = dataList2.get(0);

3、使程序员可以实现泛型算法
通过使用泛型,程序员可以实现泛型算法,这些算法可以处理不同类型的集合,可以自定义,并且类型安全且易于阅读。

泛型类型

泛型的使用示例

定义普通的类

public class Box {
    private Object object;

    public void set(Object object) {
        this.object = object;
    }

    public Object get() {
        return object;
    }
}

这样不同的开发者在使用Box类的时候,可以就往里面存入不同类型的数据,在使用的时候就容易出现运行时错误。
定义带泛型的类

public class Box<T> {
    private T t;

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}
类型形参命名规范

按照规范,类型形参名称是单个大写字母。下面是一些约定俗成的命名方式。
E - Element(Java 集合框架广泛使用)
K - Key
N - Number
T - Type
V - Value

多个类型形参

在定义接口,类,方法时可以有多个类型参数。

public class Box<K, V> {
    private K key;
    private V value;

    public Box(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }
}

使用示例:

Box<String, Integer> boxFirst = new Box<>("first", 1);
Box<String, Integer> boxSecond = new Box<>("second", 1);
原始类型

是没有任何类型实参的泛型类或接口的名称
以下面定义的泛型类来进行说明原始类型

public class Box<T> {
    private T t;

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

要创建Box<T>的参数化类型,需要为形式类型参数T提供实际类型实参。
Box<String> box = new Box<>();
如果省去实际类型实参,则创建的是Box<T>的原始类型。
Box box2 = new Box();
这里面的Box就是Box<T>的原始类型。
但是注意:

public class Box {
    private String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

像上面这种定义的时候不带泛型形参的,Box不是原始类型,要注意这一点

另外需要注意的是在原始类型对象和带实际类型实参的对象之间转换的问题:
Box<String> box = new Box<>();
Box box2 = box;
将参数化类型的对象赋值给原始类型是可以的。
但是将原始类型的对象复制给参数化类型,就会发生警告:
Box box3 = new Box();
Box<String> box4 = box3;


demo1.png

还需要注意,如果使用原始类型调用相应泛型类型中定义的泛型方法,会有警告:


demo2.png

剩下的内容在下一篇文章中进行讲解。
泛型基础二

上一篇 下一篇

猜你喜欢

热点阅读