Java - 泛型


1.前言

泛型 其实就是对类型的进行参数化(可以传类型)!

类型参数化又是啥呢?

        栗子:

实现一个类,类中有一个数组,该数组可以存放任意类型的数据!

答:将数组定义为Object(是所有类的父类)。但是如果想取出的时候,Object数组不能强转!

 原因:可以理解为 无法确定Object数组内全都是String类型,不能进行转换!


总结:Object数组不能强转

<T> 是占位符 代表该类是泛型类

class MyArray<T>{
    public T[] obj = (T[])new Object[10]; //这里其实也是错的

    public T getObj(int pos) {
        return obj[pos];
    }

    public void setObj(T val,int pos) {
        obj[pos] = val;
    }
}

public class Test {
    public static void main2(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();
        myArray.setObj(12,3);

        myArray.setObj(1,2);
        myArray.setObj(2,1);
        myArray.setObj(22,0);
        //System.out.println(myArray.getObj(0));
        MyArray<String> m = new MyArray<>();
        m.serObj("ss",1);
        //以前都是传数据,这里直接传类型
    }
}

这样做 取数的时候就不需要强转!

因此泛型存在的意义:

1.存元素的时候,会进行类型检查

2.取的时候,不需要类型转换  (都在编译的时候完成)


2.语法 

class 泛型类名称<类型形参列表> {
  // 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> { 
}

 <> 里面必须存放的是 类类型!!!


3.泛型是如何编译的?

        擦除机制:在编译的时候,将所有的T擦除成Object

Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

那有擦除的话

public T[] obj = new T[10];//为什么会报错呢?

 因为,如果是这样想,假如说有个return 整个obj数组的方法,用什么接受呢? 


4.泛型的上界

public class MyArray<E extends Number>{
    //extends 不是继承的意思,而是 E 是Number的子类或者是其自身!
}

 (拦着你,不会被擦成object 而是擦成Number)


栗子:找最大值

class Alg<T extends Comparable<T>>{
    public T findMax(T[] array){
        T max = array[0];
        for(int i = 1;i < array.length;i++){
            if(max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}

public class Test {
    public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] arr = {12,32,213,245,23,5246,24};
        System.out.println(alg.findMax(arr));
    }
}

如果我们不想new一个alg对象吗?

(泛型方法)

class Alg2{
    public static<T extends Comparable<T>> T findmax(T[] array){
        T max = array[0];
        for(int i = 1;i < array.length;i++){
            if(max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}


 泛型方法(非静态)

class Alg3{
    public <T extends Comparable<T>> T findmax(T[] array){
        T max = array[0];
        for(int i = 1;i < array.length;i++){
            if(max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}

需要new对象,但不需要传泛型参数


5.通配符

如果出现这种情况该怎么办呢?

public class TestDemo {
    public static void main(String[] args) {
    Message<Integer> message = new Message() ;
    message.setMessage(99);
    fun(message); // 出现错误,只能接收String
}
public static void fun(Message<String> temp){
    System.out.println(temp.getMessage());
}

使用通配符!

public class TestDemo {
    public static void main(String[] args) {
    Message<Integer> message = new Message() ;
    message.setMessage(55);
    fun(message);
}
// 此时使用通配符"?"描述的是它可以接收任意类型,但是由于不确定类型,所以无法修改
public static void fun(Message<?> temp){
    //temp.setMessage(100); 无法修改!
    System.out.println(temp.getMessage());

}


 因此在这里的尖括号中,直接给你擦没了

不参与类型的组成!!!!

 

6.通配符的上界/下界

? extends 类:设置泛型上限
? super 类:设置泛型下限

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值