泛型

一.对泛型的理解:
1.泛型,从字面意思上来说指的是广泛的类型,很多的类型。同时也是它的设计理念,
设计者希望创造容器,可以存放各种基类或者自定义类的对象的容器。
下面通过一些简单的代码来理解泛型:

public class  Robot{
    private int a;
    public Robot(int a) {
        this.a = a;
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
}

如上,Robot这个类只能持有整型对象a,而没有办法持有其他对象,这样的代码重用性就很不好,举个例子:在不添加其他属性的前提下,假如我们既需要整形对象1314,又需要字符串对象"一生一世",再编写新的类会增加工作量,并且我们不能为每个类型都 编写一个类,(像这样的例子有很多,比如地球的经度和纬度,根据需求不同,简单一点描述可以用int,要精确一点可以用float,甚至可以加上语言描述用字符串,同样是经纬度这个属性,我们不能再定义其它变量吧)在使用泛型之前,我们一般用Object类来解决这个问题:

public class  Robot{
    private Object a;
    public Robot(Object a) {
        this.a = a;
    }
    public Object getA() {
        return a;
    }
    public void setA(Object a) {
        this.a = a;
    }

    public static void main(String[] args) {
        Robot r1=new Robot(1314);
        int  number=(Integer)r1.getA();//需要向上转型
        Robot r2=new Robot("一生一世");
        String str= (String) r2.getA();//转型
        System.out.println(number+str);
    }
}

使用Object需要转型,并且也容易出现一些转型错误,比如把

 int  number=(Integer)r1.getA();//需要向上转型

改为:

String number=(String)r1.getA();

这个代码写好后也是可以运行的,不会提示错误,但在运行的时候会提示类型转换错误

在这里插入图片描述
因此,使用Object安全性不高,使用泛型可以很好的解决这一问题:

public class  Robot<T>{
    private T a;
    public Robot(T a) {
        this.a = a;
    }
    public T getA() {
        return a;
    }
    public void setA(T a) {
        this.a = a;
    }

    public static void main(String[] args) {
       Robot<Integer> r1=new Robot<Integer>(1314);
        Integer a1 = r1.getA();//不需要转型了
        Robot<String> r2=new Robot<String>("一生一世");
        String a2 = r2.getA();//不需要转型了
        System.out.println(a1+a2);
    }
}

在我们创建类的时候,往往不能够确定要具体使用哪一个类或者使用几种类,而是要到使用的时候才知道,这个时候就很适合使用泛型,使用时:只需要在尖括号中存入该类型。以上内容,概述了我们使用泛型的原因以及泛型类的简单使用。
二.泛型接口
泛型不止可以用于类,也可以用于接口,用法类似
interface 接口名称<泛型标识>{}//泛型接口格式

interface Usb<T>{//声明接口
    public void read();
}
public class Robot<T> implements Usb<T>{//实现接口
    private T a;
    public Robot(T a) {
        this.a = a;
    }
    public T getA() {
        return a;
    }
    public void setA(T a) {
        this.a = a;
    }
    public void read() {
    }
    public static void main(String[] args) {
        Robot<String> r=new Robot("T45");
        System.out.println(r.getA());
        Robot<Integer> r1=new Robot<Integer>(1949);
        System.out.println(r1.getA());
    }
}

三.泛型方法:
访问权限<泛型标识>泛型标识 方法名(泛型标识 方法名称 )//泛型方法格式

class Method{
    public <T>T read(T t){
        return t;
    }
}
public class Robot{
    public static void main(String[] args) {
        Method method=new Method();
        String t = method.read("T60型");
        System.out.println(t);
    }
}

四.元组
return语句只允许返回单个对象,而我们通常需要一次方法返回多个对象,这个时候我们可以使用对象容器,元组。
元组:指的是把一组可以是任意类型的对象存储在一个容器中。

public class Robot<K,T>{
    publicfinal K first;
    public final T second;
    public Robot(K first, T second) {
        this.first = first;
        this.second = second;
    }
    @Override
    public String toString() {
        return first+","+second;
    }
    public static void main(String[] args) {
        Robot<Integer,String> robot=new Robot<Integer, String>(2039,"T60");
        System.out.println(robot);
    }
}

通过继承来实现长度更长的元组,元组可以有任意长度

class MoreRobot<K,T,E>extends Robot<K,T>{
    public final E third;
    public MoreRobot(K first, T second, E third) {
        super(first, second);
        this.third = third;
    }
}

五.通配符:
来看一个使用通配符的例子:

class Root<T>{
    private T red;
    public Root(T red) {
        this.red = red;
    }
    public T getRed() {
        return red;
    }
    public void setRed(T red) {
        this.red = red;
    }
    @Override
    public String toString() {
        return this.getRed().toString();
    }
}
public class Robot{
    public static void main(String[] args) {
        Root<String> root=new Root<String>("红色T60系列");
        System.out.println(root);
        paint(root);
    }
    public static void paint(Root<?> root){//使用通配符
        System.out.println("上色:"+root);
    }
}

方法被创建时不能确定使用什么类型,使用通配符
六.擦除
java泛型是通过擦除来实现的,当使用泛型的时候,任何具体的类型都被擦除了,唯一知道的是在使用一个对象,通过下面的例子来理解:

public class Robot{
    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和Arraylist是相同的类型,在运行时两种类型都被擦除成原生类型,Arraylist。擦除会删去类型参数后的泛型类型名,并且替换为限定类型,无限定则用Object,与之前直接用Object不同,泛型擦除后会自动进行类型转换。
擦除实现了泛型,同时也带来了很多限制和问题,如:不能实例化变量,不能构造泛型数组,不能用基本类型实例化类型参数,这些内容后续更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值