Java基础-泛型

泛型

  1. 类型化参数
  2. 泛型的好处
    1. 可以节约代码
    2. 可以让代码的可读性更强
  3. 相关的名字:不同字母代表为了见名知意,都是代表类型未知
    1. T:Type 类型
    2. E:Element 元素
    3. K:key
    4. V:value
    5. ?:代表任意类型

GenericArrayType:泛化的数组类型,即T[]
ParameterizedType:参数化类型,例如: Comparator< T>,Comparator< String>
TypeVariable:类型变量,例如: Comparator< T>中的T,Map<K, V>中的K, V
WildcardType:通配符类型,例如: Comparator<?>等

  1. 泛型可以写在哪里?
    1. 类上:泛型类。例:public class ArrayList< E>
    2. 接口上:泛型接口。例:public interface List< E>
    3. 方法上:泛型方法。当方法真正执行的时候,才确定是什么类型。
      例:public static < T> boolean addAll(Collection<? super T> c, T… elements) {}
      注意:泛型方法的泛型声明放到了返回值的前面

泛型类的使用

public class GenericsTest {
    public static void main(String[] args) {
        Student<String> s1 = new Student<>("张三","棒");
        System.out.println(s1);//Student{name='张三', score=棒}
        Student<Integer> s2 = new Student<>("李四", 100);
        System.out.println(s2);//Student{name='李四', score=100}
        Student<Character> s3 = new Student<>("王五", 'A');
        System.out.println(s3);//Student{name='王五', score=A}
    }
}
class Student<T>{//类型化参数
    String name;
    T score;

    public Student() {
    }

    public Student(String name, T score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}

泛型的上限

import java.math.BigDecimal;

/*
    求俩数的和:

*/
public class GenericsTest1 {
    public static void main(String[] args) {

        SumTools<Integer> s1 = new SumTools<>(10, 20);
        System.out.println(s1.getSum());
        SumTools<BigDecimal> s2 = new SumTools<>(new BigDecimal("3.14"),new BigDecimal("2.56"));
        System.out.println(s2.getSum());
    }
}

/**
 * T extends Number & Comparable<T>
 * T:即使Number的子类也是Comparable的子类
 * 指定了当前T的上限:类型范围不能超过父类
 *
 * @param <T>
 */
class SumTools<T extends Number & Comparable<T>> {
    private T t1;
    private T t2;

    public SumTools() {
    }

    public SumTools(T t1, T t2) {
        this.t1 = t1;
        this.t2 = t2;
    }

    public T getSum() {

        if (t1 instanceof Integer) {
            Integer value = Integer.valueOf((Integer) t1 + (Integer) t2);
            return (T) value;
        }else if (t1 instanceof BigDecimal){
            BigDecimal b1 = (BigDecimal) t1;
            BigDecimal b2 = (BigDecimal) t2;
            BigDecimal decimal = b1.add(b2);
            return (T) decimal;
        }
        throw new UnsupportedOperationException("您传入的数据不能进行加法操作");
    }
}

泛型擦除

  1. 当使用参数化类型的类或接口时,如果没有指定泛型,会发生泛型擦除,自动按照最左边的第一个上限处理,如果没有指定上限,上限即为Object。
  2. 局部变量的泛型在编译后会消失
    方法形参、成员变量泛型不会消除

泛型方法

public static <T extends Comparable> void sort(T[] arr){
        for (int i = 0; i < arr.length-1 ; i++) {
            for (int j = 0; j < arr.length-1-i ; j++) {
                if (arr[j].compareTo(arr[j+1])>0){
                    T temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

类型通配符

E、T、K、V

?:代表任意类型

位置要求:需要传入具体类型的位置,不能单独使用?(声明泛型类、泛型接口、泛型方法时不能单独使用)

?extends T:传入的类型,可以是当前类型,以及当前类型的子类
?super T:传入的类型,可以是当前类型,也可是当前类型的父类

泛型的注意

泛型的限制:当使用?作为泛型的时候,只能传入null值

import java.math.BigDecimal;
import java.util.Date;

public class Test {
    public static void main(String[] args) {
        MyClass<?> myClass = new MyClass<>();
        /*myClass.setFiled(10);
        myClass.setFiled(new Date());*/
        //泛型的限制:当时用?作为泛型的时候,只能传入null值
        myClass.setFiled(null);

        //无法确定子类是哪一个,只有null是确定的
        //都是Number的子类 以及Number
        MyClass<? extends Number> myClass1 = new MyClass<>();
        /*myClass1.setFiled(20);
        myClass1.setFiled(new Integer(90));
        myClass1.setFiled(new BigDecimal(20));
        */
        myClass1.setFiled(null);

        //都是Number的父类 以及Number
        //泛型的下限
        MyClass<? super Number> myClass2 = new MyClass<>();
        myClass2.setFiled(10);
        myClass2.setFiled(new BigDecimal(20));
    }
}
class MyClass<T>{
    private String name;
    private T filed;

    public void setFiled(T filed) {
        this.filed = filed;
    }
}
import java.math.BigDecimal;
import java.util.Date;

public class GenericsEnd {

    public static void main(String[] args) {
        MyList<String> myList = new MyList<>();
        myList.add("你好");
        myList.add("世界");

        MyList<Number> m1 = new MyList<>();
        m1.add(10);
        m1.add(new BigDecimal(20));

        MyList<Object> m2 = new MyList<>();
        m2.add(10);
        m2.add(new Date());

        copy(m1,m2);
    }

    /**
     *
     * @param src ?可能是T,也可能是T的子类  MyList<? extends T> 上限
     * @param dest ?可以是T,也可以是T的父类  MyList<? super T> 下限
     * @param <T>
     */
    public static <T>void copy(MyList<? extends T> src,MyList<? super T> dest){

    }
}
class MyList<T>{
    public void add(T t){

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值