Java 泛型理解

请阅读下面代码,理解泛型真正的意义

public class Demo1<H> {
    // 不能在静态域或者方法上引用泛型
//    public static H instance;
//    // 这两种写法都是错误的,不被允许,因为静态的变量和方法所以类,
//    public static H getInstance{
//        return instance;
//    }
    public static void main(String[] args) {
//        限定泛型变量
        Dog dog1 = new Dog();
        dog1.age = 10;
        Dog dog2 = new Dog();
        dog2.age = 120;
        Dog min = min(dog1, dog2);
        System.out.println("最小的:" + min.age);
    }
    // 有时候,我们需要对类型变量加以约束,比如计算两个变量的最小,最大值。
    // T extends Comparable中,T 表示应该绑定类型的子类,Comparable表示绑定类型
    public static <T extends Comparable> T min(T a,T b){
        if (a.compareTo(b) > 0){
            return b;
        }
        return a;
    }
}
public class Dog implements Comparable<Dog>{
    int age;
    @Override
    public int compareTo(Dog dog) {
        if (this.age > dog.age){
            return 1;
        }
        return 0;
    }
}

泛型高级用法以及泛型通配符的使用
编写一个水果连的列子

在这里插入图片描述

public class Food {
}
public class Fruit extends Food{
    private String color;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}
public class Apple extends Fruit {
}
public class Orange extends Fruit {
}
public class HongFuShi extends Apple {
}

声明一个泛型类

public class GenericType<T> {
    private T data;
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}
public class Demo2 {
    public static void main(String[] args) {
//        泛型通配符
        GenericType<Fruit> genericType1 = new GenericType<>();
        Apple apple = new Apple();
        apple.setColor("红色");
        genericType1.setData(apple);
        print(genericType1);

        GenericType<Orange> genericType2 = new GenericType<>();
        Orange orange = new Orange();
        orange.setColor("黄色");
        genericType2.setData(orange);
//        GenericType<Fruit>  GenericType<Orange>  这两者之间没有任何关系,所以编译不过
//        为了解决这个问题,于是提出了一个泛型通配符
//        print(genericType2);
//        ? extends X 表示类型的上界是 X
//        调用下面这个方法完美的解决了上面的问题
        print2(genericType2);

        GenericType<? extends Fruit> genericType3 = genericType2;
//        这样是不被允许的,
//        genericType3.setData(apple);
//        genericType3.setData(orange);
//        get方法则没问题,会返回一个Fruit类型的值。
        Fruit fruit = genericType3.getData();
//        为什么会出现上面的问题,因为 ? extend Fruit 表示类型的上界,类型的上界是Fruit,所以编译器会
//        确切的知道 get 返回的类型,至于 set方法只知道传入的是Fruit的下界,但是至于具体是哪个子类编译器不知道
//        总结:主要用于安全的数据访问,


        GenericType<? super Fruit> superType = new GenericType<>();
        superType.setData(new Fruit());
        superType.setData(new Orange());
        superType.setData(new HongFuShi());
        superType.setData(new Food());
        Object data = superType.getData();
//      ? super Fruit 表示类型的下界,类型参数是 Fruit的超类(包括Fruit本身),那么get方法返回的是
//        fruit 的超类,那么到底是哪个超类?编译器不知道,但是 Object一定是它的超类,所以get方法返回的
//        Object,编译器是可以确切知道的.对于set方法来说,编译器不知道它需要的确切类型,但是知道Fruit的
//        子类是可以安全的转型为Fruit
//        总结:主要用于安全的数据写入,可以写入Fruit 和 Fruit的子类

    }

    public static void userSuper(){
        GenericType<Food> foodGenericType = new GenericType<>();
        GenericType<Fruit> fruitGenericType = new GenericType<>();
        GenericType<Apple> appleGenericType = new GenericType<>();
        GenericType<Orange> orangeGenericType = new GenericType<>();
        //        ? super X
//        表示传递给方法的参数,必须是X的父类,或者本身
        printSuper(foodGenericType);
        printSuper(fruitGenericType);
//     下面这两个调用会有问题,编译不会通过
//        printSuper(appleGenericType);
//        printSuper(orangeGenericType);


    }

    public static void print(GenericType<Fruit> genericType){
        System.out.println(genericType.getData().getColor());
    }

    public static void print2(GenericType<? extends Fruit> genericType){
        System.out.println(genericType.getData().getColor());
    }

    public static void printSuper(GenericType<? super Fruit> genericType){
        System.out.println(genericType.getData());
    }
    /*
    * Java 语言中的泛型规则不一样,它只是存在于源码阶段,在编译后的字节码文件中,就已经替换成原生的类型
    * (Raw Type, 也称为裸类型),并且在相应的地方插入了强制类型的转化
    * 对于运行时的List<String> 和 List<Integer>就是同一个类型
    * Java语言中的泛型实现方法在编译成Class文件之后,就会檫除,也就是一种伪泛型
    * 所以导致下面 method这个方法编译不通过
    * */
    public static void method(List<String> msg){
        System.out.println("msg");
    }

    public static void method(List<Integer> msg){
        System.out.println("msg");
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值