Java泛型详解(自定义泛型、通配符。。。)

文章目录

    • 1、泛型概述
    • 2、泛型作用
    • 3、泛型使用
    • 3、自定义泛型
    • 4、泛型在继承中的体现
    • 5、通配符的使用
      • 5.1、使用通配符后的数据读取和写入要求


1、泛型概述

      所谓泛型,就是允许在定义类、接口时通过提供标识表示类中的某个属性的类型或者是某个方法的返回值类型及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也成为类型实参)。

一些常用的泛型类型变量:
E:元素(Element),多用于java集合框架
K:关键字(Key)
N:数字(Number)
T:类型(Type)
V:值(Value)


2、泛型作用

  • 泛化。可以用T代表任意类型Java语言中引入泛型是一个较大的功能增强不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了,这带来了很多好处。

  • 类型安全。泛型的一个主要目标就是提高ava程序的类型安全,使用泛型可以使编译器知道变量的类型限制,进而可以在更高程度上验证类型假设。如果不用泛型,则必须使用强制类型转换,而强制类型转换不安全,在运行期可能发生ClassCast Exception异常,如果使用泛型,则会在编译期就能发现该错误。

  • 消除强制类型转换。泛型可以消除源代码中的许多强制类型转换,这样可以使代码更加可读,并减少出错的机会。

  • 向后兼容。支持泛型的Java编译器(例如JDK1.5中的Javac)可以用来编译经过泛型扩充的Java程序(Generics Java程序),但是现有的没有使用泛型扩充的Java程序仍然可以用这些编译器来编译。


3、泛型使用

没有使用泛型的情况

public class Main {

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);

        //问题一:类型不安全
        arrayList.add("皮皮虾");

        for (Object score: arrayList) {

            //问题二:强转时,可能出现ClassCastException
            Integer score1 = (Integer) score;
            System.out.println(score1);
        }
    }
}

在这里插入图片描述
使用泛型的情况

Java泛型详解(自定义泛型、通配符。。。)_第1张图片

public class Main {

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);
//        list.add("皮皮虾");

        for (Integer score: list) {
            //避免强转
            int stuscore = score;
            System.out.println(stuscore);
        }
    }
}

在这里插入图片描述

在集合中使用泛型的情况

public class Main {

    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();

        map.put("皮皮虾",99);
        map.put("小明",87);
        map.put("小花",90);

        System.out.println(map);
    }
}

在这里插入图片描述
总结

  • jdk5.0新特性
  • 集合接口或集合类在jdk5.0时都修改为带泛型的结构
  • 在实例化集合类时,可以指明具体的泛型类型
  • 如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型
  • 注意:泛型的类型必须是类,不能时基本数据类型。需要使用基本数据类型的位置,使用包装类替换。

3、自定义泛型

自定义泛型类

//自定义泛型类
public class Order<T> {

    String name;
    int id;

    //类的内部结构就可以使用类的泛型

    T orderT;

    public Order() {
    }

    public Order(String name, int id, T orderT) {
        this.name = name;
        this.id = id;
        this.orderT = orderT;
    }

    public T getOrderT() {
        return orderT;
    }

    public void setOrderT(T orderT) {
        this.orderT = orderT;
    }
}

测试类

//如果定义了泛型类,实例化没有指明类的泛型,则默认为Object类型
Order order = new Order();
order.setOrderT(1);
order.setOrderT("皮皮虾");

Java泛型详解(自定义泛型、通配符。。。)_第2张图片

//实例化时指明类的泛型
Order<String> stringOrder = new Order<>();
stringOrder.setOrderT("Hello");

在这里插入图片描述

建议实例化时指明类的泛型


4、泛型在继承中的体现

Java泛型详解(自定义泛型、通配符。。。)_第3张图片

Java泛型详解(自定义泛型、通配符。。。)_第4张图片


5、通配符的使用

通配符:?

public class Main {

    public static void print(List<?> list) {
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }
    }

    public static void main(String[] args) {
        List<Object> list1 = null;
        List<String> list2 = null;

        List<?> list = null;
        list = list1;
        list = list2;

        print(list1);
        print(list2);
    }
}

5.1、使用通配符后的数据读取和写入要求

public static void main(String[] args) {

        List<?> list = null;

        List<Object> list3 = new ArrayList<>();
        list3.add("a");
        list3.add("b");
        list3.add("c");

        list = list3;
        //添加(写入):对于List<?>就不能向起内部添加数据除了null
//        list.add("f");
        list.add(null);

        //读取:允许读取数据,读取的数据类型为Object
        Object o = list.get(1);
        System.out.println(o);
    }

在这里插入图片描述


觉得不错的小伙伴可以点赞关注和收藏哦!

Java学习路线目录索引

在这里插入图片描述

你可能感兴趣的:(Java,java,泛型)