Java泛型基础总结(代码总结)

Java泛型基础总结(代码总结)

1.泛型类

假设不使用泛型,可存储任意类型元素,返回的是Object类型,但是后期操作容易存在类型转换错误。
泛型的本质:类型参数化,将所操作的数据类型指定为一个参数

泛型类的定义

/*
泛型类的定义
T 创建对象的时候来指定的数据类型
 */
public class Generic<T> {
    private T key;

    public Generic() {
    }

    @Override
    public String toString() {
        return "Generic{" +
                "key=" + key +
                '}';
    }

    public Generic(T key) {
        this.key = key;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}

测试类定义

public class Demo {
    public static void main(String[] args) {
        //泛型类在创建对象时来制定具体的类型
        Generic<String> strGeneric = new Generic<>("a");
        String key1 = strGeneric.getKey();
        System.out.println(key1);

        Generic<Integer> intGeneric = new Generic<>(100);
        Integer key2 = intGeneric.getKey();
        System.out.println(key2);

        //若没有指定类型,则按照Object类处理
        Generic generic = new Generic("abc");
        Object key3 = generic.getKey();
        System.out.println(key3);
    }
}

个人理解:可以把自定义的泛型类理解为集合(如ArrayList集合)。其方法都需要自定义.

1.2应用:实现一个抽奖器

泛型类

public class ProductGetter<T> {
    private T product;

    Random random = new Random();

    //奖品池 集合
    ArrayList<T> list = new ArrayList<>();


    public void addProduct(T t){
        list.add(t);
    }

    public T getProduct() {
        product = list.get(random.nextInt(list.size()));
        return product;
    }
}
1.3泛型类派生子类

泛型父类

public class Parent<E> {
    private E value;

    public Parent() {
    }

    public Parent(E value) {
        this.value = value;
    }

    public E getValue() {
        return value;
    }

    public void setValue(E value) {
        this.value = value;
    }
}

泛型子类1

public class ChildFirst<T> extends Parent<T>{
    @Override
    public T getValue() {
        return super.getValue();
    }
}

这里泛型子类1也是泛型,所以其泛型标识必须一致,都为T或者E


泛型子类2

public class ChildSecond extends Parent<Integer>{
    @Override
    public Integer getValue() {
        return super.getValue();
    }

    @Override
    public void setValue(Integer value) {
        super.setValue(value);
    }
}

这里泛型子类2就不是泛型类,就要明确派生类型。


测试类

public class Demo {
    public static void main(String[] args) {
    	//使用时再确定泛型类型
        ChildFirst<String> childFirst = new ChildFirst<>();
        childFirst.setValue("abc");
        String value = childFirst.getValue();
        System.out.println(value);

		//子类已经是确定的类
        ChildSecond childSecond = new ChildSecond();
        childSecond.setValue(45);
        Integer value1 = childSecond.getValue();
        System.out.println(value1);
    }
}
2.泛型接口
public interface Generator<T> {
    T getKey();
}

泛型实现类1,其不是泛型类,所以需要明确泛型接口的数据类型

public class Apple implements Generator<String> {
    @Override
    public String getKey() {
        return "hello generator";
    }
}

泛型实现类2,其是泛型类,所以泛型的标识要包含泛型接口额标识符

public class Pair<T,E> implements Generator<T>{
    private T key;
    private E value;

    public Pair(T key, E value) {
        this.key = key;
        this.value = value;
    }

    public Pair() {
    }

    @Override
    public T getKey() {
        return key;
    }

    public E getValue() {
        return value;
    }
}

测试类

public class Demo5 {
    public static void main(String[] args) {
        Apple apple = new Apple();
        String key = apple.getKey();
        System.out.println(key);

        System.out.println("====================");
        Pair<String,Integer> pair = new Pair<String, Integer>("James",23);
        //类似于Map
        String key1 = pair.getKey();
        Integer value = pair.getValue();
        System.out.println(key1+value);

    }
}
3.泛型方法

以前面的抽奖器为例

public class ProductGetter<T> {
    private T product;

    Random random = new Random();

    //奖品池 集合
    ArrayList<T> list = new ArrayList<>();


    public void addProduct(T t){
        list.add(t);
    }

    public T getProduct() {
        product = list.get(random.nextInt(list.size()));
        return product;
    }
/*
定义了一个泛型方法
<E>泛型列表 这是泛型方法的标志 具体类型 ,由调用方法时指定
 */
    public <E> E getProduct(ArrayList<E> list){
        return list.get(random.nextInt(list.size()));

    }
    /*
    泛型可变参数的定义
     */
    public static <E> void print(E... e){
        for (int i = 0; i < e.length; i++) {
            System.out.println(e[i]);
        }
    }
}

测试类

public class Demo6 {
    public static void main(String[] args) {
        ProductGetter<Integer> productGetter = new ProductGetter<>();
        ArrayList<String> stringArrayList = new ArrayList<>();
        stringArrayList.add("苹果手机");
        stringArrayList.add("华为手机");
        stringArrayList.add("笔记本电脑");
        stringArrayList.add("扫地机器人");

        //对泛型方法的调用,类型是通过调用方法的时候指定  泛型方法独立于泛型类
        //Demo3里的是泛型类的成员方法  注意泛型方法和成员方法的区别
        String product = productGetter.getProduct(stringArrayList);
        System.out.println(product+product.getClass().getSimpleName());

        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1000);
        integers.add(200);
        integers.add(2000);
        //成员方法
        Integer product1 = productGetter.getProduct(integers);
        System.out.println(product1+product1.getClass().getSimpleName());

        productGetter.print(1,2,3,4,5);
    }
}
4.类型通配符

首先定义一个泛型类

public class Box<T> {
    private T first;

    public T getFirst() {
        return first;
    }
    public void setFirst(T first) {
        this.first = first;
    }
}

测试类

public class Demo7 {
    public static void main(String[] args) {
        Box<Number> box1 = new Box<Number>();
        box1.setFirst(100);
        showBox(box1);

        Box<Integer> box2 = new Box<Integer>();
        box2.setFirst(200);
        showBox(box2);
    }
    //?就是类型通配符  类型通配符代表的就是类型实参,而不是类型形参
    //? extends Number  类型通配符的上限  只能传Number或者其子类
    public static void showBox(Box<? extends Number> box) {
        Number first = box.getFirst();
        System.out.println(first);
    }
}

?就是类型通配符。其代表的就是类型实参,而不是类型形参;
? extends Number 类型通配符的上限,参数只能传Number或者其子类。


还有类型通配符的下限
? super Number 类型通配符的下限,参数只能传Number或者其父类;


5.类型擦除
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
		
System.out.println(l1.getClass() == l2.getClass());

输出结果为true。这是因为类型擦除的缘故
通俗地将,泛型类和普通类在JVM里是没有什么差别的。
其实,
在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,则会被转译成普通的 Object 类型,如果指定了上限则类型参数就被替换成类型上限。下限也是。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值