java中的泛型

为什么要用泛型?

1)为了避免类型转换异常

2)使用泛型类,泛型接口,可以复用代码,降低耦合。

类、接口和方法代码可以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起同一套代码,可以用于多种数据类型,这样,不仅可以复用代码,降低耦合,同时,还可以提高代码的可读性和安全性。

—————————————————————————————————————————>

首先看一下这段代码:

public class GenericTest {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("qqyumidi");
        list.add("corn");
        list.add(100);

        for (int i = 0; i < list.size(); i++) {
            String name = (String) list.get(i); // 1
            System.out.println("name:" + name);
        }
    }
}
 

定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。

在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”(类转化异常)异常。因此,导致此类错误编码过程中不易发现。

在如上的编码过程中,我们发现主要存在两个问题:1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,该对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

2//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常—————————————————————————————————————————>

怎么理解泛型?

"泛型"字面意思就是广泛的类型

容器类是基于泛型的,不理解泛型,我们就难以深刻理解容器类(泛型类和泛型接口都是容器)。

泛型类其实是容器类,用来容纳并管理多项数据类型的。

public class Student<T> {
    //定义一个泛型类,其中泛型类型为T,在类中定义一个泛型类型的成员变量。
    private T activity;
}

T是泛型通配符,,T表示类型参数,泛型就是类型参数化(类型不固定,以参数的形式传递进来),处理的数据类型不是固定的,而是可以作为参数传入。—————————————————————————————————————————>

1)如何定义泛型类?
2)如何定义泛型接口?
3)有界泛型与通配符
4)泛型类型参数到底是什么呢?


泛型主要用于限定约束数据类型的.避免强制类型转化

泛型泛型接口、泛型类和泛型方法 ; 泛型在集合中的使用

泛型类:把泛型定义在类上;

格式public class Student<T>{ }

注意:泛型类型必须是引用类型。   泛型类用于限定谁的数据类型/T表示形式参数

 

泛型方法:把泛型定义在方法上

格式: public <泛型类型>返回类型 方法名(泛型类型)

/**
 * Created on 2016/8/5.
 * Author:crs
 * Description:泛型方法的使用  把泛型定义在方法的参数上
 */
public class FanXing {
    public <QQ> void show(QQ qq) {
        System.out.print(qq);
    }
}

泛型接口: 把泛型定义在接口上

格式: public interface 接口名<泛型类型>{  }


核心问题是: 泛型类型什么时候确定?泛型类中,创建对象的时候确性泛型的类型

private List<Vehicle> list = null;
声明集合的时候,明确指定了集合中存储的数据类型,不能存储其他类型的数据,否则编译不通过。

—————————————————————————————————————————>

关键是泛型如何使用?一、定义一个泛型接口

/**
 * Created on 2016/8/5.
 * Author:crs
 * Description:定义泛型接口,泛型接口如何使用?
 */
public interface FanInterface<TT> {
    void show(TT tt);
}
二、定义一个类来实现带有泛型的接口:
1、在实现接口的时候,明确了泛型的数据类型 

/**
 * Created on 2016/8/5.
 * Author:crs
 * Description:定义泛型接口,泛型接口如何使用?
 */
public class FanInterfaceImplements implements FanInterface<String> {
    @Override
    public void show(String s) {
        System.out.print(s);
    }
}
2、在实现接口的时候不明确泛型的实现类型    //在创建对象的时候,明确泛型的数据类型

/**
 * Created on 2016/8/5.
 * Author:crs
 * Description:定义泛型接口,泛型接口如何使用?
 */
public class FanInterfaceImplements<TT> implements FanInterface<TT> {
    @Override
    public void show(TT tt) {
        System.out.print(tt);
    }
}
//在创建对象的时候,明确泛型的数据类型
FanInterfaceImplements<String> fanInterfaceImplements = new FanInterfaceImplements<>();
fanInterfaceImplements.show("一世红尘");

//泛型应用最广泛的地方是把泛型定义在接口上

—————————————————————————————————————————>
泛型通配符<?>
在创建集合的时候,不知道集合里面要放什么类型的元素?
<?> 任意类型,如果没有明确,那就是Object类型以及任意的Java类
? extends E 向下限定,通配符?代表的只能是E类及其子类
向下限定、泛型的类型

—————————————————————————————————————————>

1)凡是出现TT的地方均表示接受相同的来自外部的类型实参。
2)在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,由于接收来自外部使用时候传入的类型实参。
3)通配符一般是使用 ? 代替具体的类型实参。注意了,此处是类型实参,而不是类型形参!
4)可以使用泛型去简化开发,且能很好的保证代码质量。

—————————————————————————————————————————>

项目中泛型的使用:

public interface ListItem extends Serializable{

	<T extends ListItem> T newObject();

	void praseFromJson(JsonUtil jsonUtil);
}
这是一个抽象方法,它的返回值类型是泛型类型,必须是ListItem类型或者其子类类型,

    @Override
    public Address newObject() {
        return new Address();
    }

这种做法的好处是:直接可以获取一个当前类的对象。由于项目中存在大量的数据模型...

—————————————————————————————————————————>

public class Teacher<K,V> {
    //定义泛型类的时候,指定两个泛型类型。
    //定义泛型类型的成员变量
    //K,V:表示泛型通配符
    private K k;
}
在定义一个泛型类的时候,在 “<>”之间定义形式类型参数,例如:“class TestGen<K,V>”,其中“K” , “V”不代表值,而是表示类型。

泛型类型必须是引用类型。

实例化泛型对象的时候,一定要在类名后面指定类型参数的值(类型)

        //实例化泛型类的时候,一定要指明泛型类型。
        //创建泛型对象
        Student<String> s = new Student<>();

        //定义一个接口对象
        IView<String> iView = null;
        iView = new IViewImpl("陈如水");

————————————————————————————————>

泛型方法:把泛型定义在方法上

格式: public <泛型类型>返回类型 方法名(泛型类型)

public class FanXing {  
    public <QQ> void show(QQ qq) {  
        System.out.print(qq);  
    }  
}


泛型类型什么时候确定?
二、定义一个类来实现带有泛型的接口:
1、在实现接口的时候,明确了泛型的数据类型 
泛型应用最广泛的地方是把泛型定义在接口上

public interface IView<T> {
    //☆定义一个泛型类型的接口,其中抽象方法的返回值为泛型类型
    //定义抽象方法,抽象方法的返回值就是泛型类型
    T getType();
}

public class IViewImpl<T> implements IView<T> {
    //定义泛型接口的子类
    //泛型接口的实现方式:在子类的定义上也要声明泛型类型。

    private T var;

    //通过构造函数为泛型类型设置值
    public IViewImpl(T var) {
        this.var = var;
    }

    @Override
    public T getType() {
        return this.var;
    }
}

定义一个泛型类,其中包含两个泛型类型。
定义一个泛型类型的成员变量。
在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,由于接收来自外部使用时候传入的类型实参。
泛型接口能够方便的应用于工厂模式,能够创建各种不同类型的对象。


有界泛型:

public class Info<T extends Number> {
    //泛型只能是数字类型

    private T var;

    public T getVar() {
        return var;
    }

    public void setVar(T var) {
        this.var = var;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值