java泛型学习

发布于:2024-06-24 ⋅ 阅读:(156) ⋅ 点赞:(0)

没有java泛型会存在的问题

  1. 假设我们有一个方法,希望通过传递不同类型的参数,输出不同类型的对象值。正常情况下我们可能会写不同的方法来实现,但是这样会导致类不断增加,并且类方法很相似,不能够复用。进而导致类爆炸
  2. 假设有一个方法,我们希望传参具有一定约束,而不是像Object对象一样随便传参

java泛型的常见使用

包装类型参数

  1. 定义一个方法,打印各种包装类型
public class Generics1<T> {
    private T name;

    public Generics1(T name) {
        this.name = name;
    }

    public void allPrint(){
        System.out.println(name);
    }
}
  • main
public class Main {

    public static void main(String[] args) {
        Generics1<Integer> integerGenerics1 = new Generics1<>(1);
        integerGenerics1.allPrint();

        Generics1<String> stringGenerics2 = new Generics1<>("222222");
        stringGenerics2.allPrint();

        Generics1<Long> longGenerics3 = new Generics1<>(222L);
        longGenerics3.allPrint();
    }
}

注意:泛型里面必须是对象,或者包装类型。基础类型是不被允许的

多个包装类型参数

  1. 两个泛型参数
public class Generics2<T,K> {

    private T name;
    private K context;

    public Generics2(T name,K context) {
        this.name = name;
        this.context=context;
    }

    public void allPrint(){
        System.out.println(name);
        System.out.println(context);
    }
}
  • Main
public class Main2 {

    public static void main(String[] args) {
        Generics2<String, Integer> stringIntegerGenerics2 = new Generics2<>("1111", 222);
        stringIntegerGenerics2.allPrint();

    }
}

上界继承

  1. 限定使用者传递的参数必须继承某个父类之下
public class Generics3<T extends Vehicle> {

    private T name;

    public Generics3(T name) {
        this.name = name;
    }

    public void allPrint(){
        System.out.println(name.getName());
    }
}
  • 父类
public class Vehicle {


    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void run(String name){
        System.out.println(name+"can run");
    }
}
  • 子类
public class Car extends Vehicle{

    private Integer wheel;



    public Integer getWheel() {
        return wheel;
    }

    public void setWheel(Integer wheel) {
        this.wheel = wheel;
    }


    public void getWheel(String name,Integer wheel) {
        System.out.println(name+"有"+wheel+"个轮子");
    }
}
  1. 可以不是父 类,可以是接口。接口有更好的扩展性
public class Generics4<T extends Vehi> {

    private T vehics;

    public Generics4(T vehics) {
        this.vehics = vehics;
    }

    public void allPrint(){
        vehics.run();
    }
}
  • 接口
public interface Vehi {
    void run();
}

使用上界继承的好处

  1. 使用上界继承的最大好处是:必然我们会用到接口或者父类,那么我们可以抽取一些公共方法,放到父类或接口里面。不同的实现拥有不同的处理方式。具备更强的扩展性
  2. java里面虽然有Object来实现传递各种类型参数(如下),但是不推荐这么做。会产生一种。例如:当我们从List取值的时候,java是无法推断里面值的类型,编译器就会报错

错误示例

上面这个代码在运行时,获取第二个值时,就会报错。
使用Object,在编译阶段是没有问题的,但是在运行时就会出现问题。
而使用泛型,在编译阶段,就能检查出来问题

泛型函数:Generic method

泛型函数方法的定义

  1. 在返回类型前添加泛型类型: 。参数设置为泛型
private static <T> void printAll(T myOb){
}
  1. 举例子
public class Main5 {

    public static void main(String[] args) {
        printAll(new BigCar(3,"myba"));
    }


    private static <T> void printAll(T myOb){
        System.out.println(myOb);
    }
}
  1. 同理也可以使用上界继承限定
    private static <T> void printAll(T myOb){
        System.out.println(myOb);
    }
private static <T extends Vehicle & Vehi> void printAll(T myOb){
    System.out.println(myOb);
}
  1. 配置多个参数
private static <T,K> void printAll2(T myOb,K myob2){
    System.out.println(myOb);
    System.out.println(myob2);
}

泛型通配符

  1. String,Integer,Long我们在传递参数时,可以用Object来定义参数。但是:List,却不是List的子类。这种情况怎么处理?
  2. 通配符的使用
private static void printAll(List<?> myOb){
    System.out.println(myOb);
}

上界通配符

  1. 意思是,传入的参数必须是Vehi的子类或者实现,或者本身
private static void printAll(List<? extends Vehi> myOb){
    System.out.println(myOb);
}

下界通配符

  1. 意思是传入的参数必须是Car的父类或者Car本身
private static void printAll(List<? super Car> myOb){
    System.out.println(myOb);
}

网站公告

今日签到

点亮在社区的每一天
去签到