阶段一/常用工具类/Java泛型

 

 

泛型概述

  • Java SE7及以后的版本中,构造方法中可以省略泛型类型,例如List<String> list = new ArrayList<>();
  • 泛型变量声明的类型必须匹配传递给实际对象的类型,例如下面这种是不可以的,Cat是Animal类的子类,但是List<Animal> list = new ArrayList<Cat>();这种是不被允许的,会报错,Error:不兼容的类型: java.util.ArrayList<com.imooc.Cat>无法转换为java.util.List<com.imooc.Animal>,只可以写成类似这种List<Cat> list = new ArrayList<Cat>();
  • 泛型作为参数传递给其的对象必须是同一类型,不能是其子类
  • 若需要兼容其子类,需要在前面添加T extends,此处T是啥不重要
  • 若需要兼容其父类,需要在前面添加T super,此处T是啥不重要

作用

  • 提高java程序的类型安全:在集合中可以添加Object类型的对象,如果在不使用泛型的情况下定义了一个ArrayList对象,那么各种类的对象都可以添加到该集合中,而在从集合中取值时,都需要进行强制类型转换,可以把取出的对象转换成任意类型,但是编译时不会报错,但是运行时会发生异常
  • 消除强制类型转换:泛型可以消除源代码中的许多强制类型转换,这样可以使代码的可读性更好,并减少出错的机会

泛型作为方法参数和方法重载

先上代码

Goods是Book的父类

abstract public class Goods {
    public abstract void sell();
}
public class Book extends Goods{
    @Override
    public void sell() {
        System.out.println("sell books");
    }
}

下面我们来看看

  • 泛型作为参数传递给其的对象必须是同一类型,不能是其子类
  • 若需要兼容其子类,需要在前面添加? extends
public class GoodsSeller {
    // 泛型作为方法参数,在前面添加? extends,则可以传入该类即其子类的列表
    // 即列表中的元素可以是Goods类型的,也可以是其子类,例如Book等
    public void sellGoods(List<? extends Goods> goods){
        // 调用sell方法
        System.out.println("sellGoods: ");
        for(Goods good: goods)
            good.sell();
    }
    // 泛型作为参数,传进来的必须和声明的是一致的,即列表中的对象只能是Goods类型的,不能使其子类
    public void sellMethod(List<Goods> goods){
        System.out.println("sellMethod: ");
        for(Goods good: goods)
            good.sell();
    }
}
public class GoodsTest {
    public static void main(String[] args){
        //定义book相关的List
        List<Book> books = new ArrayList<Book>();
        books.add(new Book());
        books.add(new Book());

        GoodsSeller goodsSeller = new GoodsSeller();
        // 报错,不兼容的类型: java.util.List<com.imooc.generic.Book>
        // 无法转换为java.util.List<com.imooc.generic.Goods>
//        goodsSeller.sellMethod(books);
        goodsSeller.sellGoods(books); // 这样就可以了
    }
}

关于方法重载

  • 泛型作为参数的方法总是最后一个调用的
  • 当我们用T(T extends xxx)做类型时,不能再以xxx这个类型作为重载,例子如下:
public class GenericMethod {
    public <T extends Number> void printValue(T t){
        System.out.println("泛型:" + t);
    }
    // 和第一个T作为参数的方法形成重载,泛型作为参数的方法总是最后一个调用的
    public void printValue(Integer t){
        System.out.println("Integer:" + t);
    }
    // 报错:名称冲突: printValue(java.lang.Number)和<T>printValue(T)具有相同疑符
    // 即和第一个T作为参数的方法一样,说明他们虽然表面看来不一样,但编译后的形式是一样的,故不合法
//    public void printValue(Number t){
//        System.out.println("Integer:" + t);
//    }
    public static void main(String[] args){
        GenericMethod gm = new GenericMethod();
        gm.printValue(123);
        gm.printValue(5.0f);
        gm.printValue(10.0);
    }
}

自定义泛型类

就直接上代码吧,好像没啥要说的

// 相当于把类进行了参数化
public class NumberGeneric<T> {
    private T num;
    public T getNum(){
        return num;
    }

    public void setNum(T num) {
        this.num = num;
    }

    public static void main(String[] args){
        NumberGeneric<Integer> intNumber = new NumberGeneric<>();
        intNumber.setNum(3);
        System.out.println("Integer: " + intNumber.getNum());

        NumberGeneric<Double> doubleNumber = new NumberGeneric<>();
        doubleNumber.setNum(6.);
        System.out.println("Double: " + intNumber.getNum());
    }
}

输出

Integer: 3
Double: 3
public class TwoNumGeneric<T, X> {
    private T num1;
    private X num2;
    public void genNum(T num1, X num2){
        this.num1 = num1;
        this.num2 = num2;
    }

    public T getNum1() {
        return num1;
    }

    public void setNum1(T num1) {
        this.num1 = num1;
    }

    public X getNum2() {
        return num2;
    }

    public void setNum2(X num2) {
        this.num2 = num2;
    }

    public static void  main(String[] args){
        TwoNumGeneric<Integer, Float> numObj = new TwoNumGeneric<>();
        numObj.genNum(25, 5.f);
        System.out.println("num1 = " + numObj.getNum1());
        System.out.println("num2 = " + numObj.getNum2());
    }
}

输出:

num1 = 25
num2 = 5.0

 

 

参考:慕课网-Java体系课

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值