Java泛型

文章目录

提示:以下是本篇文章正文内容,下面案例可供参考

一、泛型概念

所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。

这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时) 确定 (即传入实际的类型参数,也称为类型实参)

二、泛型的使用

1. 泛型的使用

  • 在集合中使用泛型
  • 总结:
  • 1.集合接口或集合类在jdk5.0时都能修改为带泛型的结构
  • 2.在实例化集合类时,可以指明具体的泛型类型
  • 3.指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(属性、方法、构造器)使用到类的泛型的位置,都指定为实例化的泛型类型
  • 比如:add(E e) --->实例化以后:add(Interger e)
  • 4.注意点:泛型的类型必须是类,不能是基本数据类型,需要基本数据类型的地方,用包装类
  • 5.如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型
cpp 复制代码
package com.tyust.edu;

import org.junit.Test;

import java.util.*;

/**
 * 泛型的使用
 * 在集合中使用泛型
 *
 * 总结:
 * 1.集合接口或集合类在jdk5.0时都能修改为带泛型的结构
 * 2.在实例化集合类时,可以指明具体的泛型类型
 * 3.指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(属性、方法、构造器)使用到类的泛型的位置,都指定为实例化的泛型类型
 * 比如:add(E e)  --->实例化以后:add(Interger e)
 * 4.注意点:泛型的类型必须是类,不能是基本数据类型,需要基本数据类型的地方,用包装类
 * 5.如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型
 *
 *
 *
 * 如何自定义泛型结构:泛型类、泛型接口、泛型方法
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 8:43
 */
public class GenericTest {

    //在集合中使用泛型之前的情况
    @Test
    public void test1(){
        ArrayList list = new ArrayList();
        //需求:存放学生的成绩
        list.add(78);
        list.add(78);
        list.add(78);
        list.add(78);
        //问题一:类型不安全
        list.add("Tom");

        for(Object score:list){
            //问题二:强转时,可能出现
//            ClassCastException异常
            int stuScore = (Integer)score;

            System.out.println(stuScore);
        }
    }

    //在集合中使用泛型的情况 以ArrayList为例
    @Test
    public void test2(){
        ArrayList<Integer>list = new ArrayList<>();

        list.add(89);
        list.add(89);
        list.add(89);
        list.add(89);

        //编译时,就会进行类型检查,保证数据的安全
//        list.add("Tom");

        //方法一:
//        for(Integer score : list){
//            //避免了强转操作
//            int stuscore = score;
//            System.out.println(stuscore);
//        }

        //方式二
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            int stuScore = iterator.next();
            System.out.println(stuScore);
        }


    }

    //在集合中使用泛型的情况 以HashMap为例
    @Test
    public void test3(){
        Map <String,Integer> map = new HashMap<String,Integer>();

        map.put("Tom",87);
        map.put("Mary",100);
        map.put("Java",97);

//        map.put(123,abx);
        //泛型的嵌套
        Set<Map.Entry<String,Integer>>entry = map.entrySet();
        Iterator<Map.Entry<String,Integer>> iterator = entry.iterator();
        while (iterator.hasNext()){
            Map.Entry<String,Integer> e = iterator.next();
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key + "--->"+value);
        }


    }


}

2.如何自定义泛型结构:泛型类、泛型接口、泛型方法

cpp 复制代码
package com.tyust.edu;


import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 *  如何自定义泛型结构:泛型类、泛型接口、泛型方法
 *1.关于自定义泛型类、泛型接口
 *
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:23
 */
public class GenericTest1 {


    @Test
    public void test1(){
        //如果定义了泛型类,实例化没有指明类的泛型,则认为
        //此泛型类型为Object类型
        Order order = new Order();
        order.setOrderT(123);
        order.setOrderT("ABC");
        //建议:实例化时指明类的泛型
        Order<String > order1 = new Order<String>("orderAA",1001,"Order:AA");
        order1.setOrderT("AA:hello");

    }

    @Test
    public void test2(){
        SubOrder sub1 = new SubOrder();
        //由于子类在继承带泛型的父类时,指明了泛型类型,
        //则实例化子类对象时,不再需要指明泛型。
        sub1.setOrderT(1122);

        SubOrder1<String >sub2 = new SubOrder1<>();
        sub2.setOrderT("order2...");


    }

    @Test
    public void test3(){
        //泛型不同的引用不能相互赋值
        ArrayList<String > list1 = null;
        ArrayList<Integer > list2 = null;
//        list1 = list2;


    }

    //测试泛型方法
    @Test
    public void test4(){
        Order<String>order = new Order<>();
        Integer[] arr = new Integer[]{1,2,3,4};
        //泛型方法在调用时,指明泛型参数的类型
        List<Integer> list = order.copyFromArryToList(arr);
        System.out.println(list);
    }
}
cpp 复制代码
package com.tyust.edu;

import java.util.ArrayList;
import java.util.List;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:27
 */
public class SubOrder extends Order<Integer> {//SubOrder  不是泛型类
    public static  <E> List<E> copyFromArryToList(E[] arr){
        ArrayList<E> list = new ArrayList<>();
        for(E e:list){
            list.add(e);
        }
        return list;
    }
}
cpp 复制代码
package com.tyust.edu;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:29
 */
public class SubOrder1<T> extends Order<T> {//SubOrder1<T>  仍然是泛型类
}

3.静态方法中不能使用类的泛型

cpp 复制代码
package com.tyust.edu;


import java.util.ArrayList;
import java.util.List;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:18
 */
public class Order<T> {
    String orderName;
    int orderId;
    T orderT;

    public Order(){
        //编译不通过
//        T[] arr = new T[10];
        T[]arr = (T[])new Object[10];
    }

    public Order(String orderName,int orderId,T orderT){
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderT = orderT;
    }

    public T getOrderT(){
        return this.orderT;
    }

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

    //静态方法中不能使用类的泛型
//    public static void show(T orderT){
//        System.out.println(orderT);
//    }

    //泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
    //换句话说,泛型方法所属的类是不是泛型类都没有关系
    //泛型方法,可以声明为静态的。原因:泛型参数在调用方法时确定的,并不是在实例化类时确定
    public static  <E> List<E> copyFromArryToList(E[] arr){
        ArrayList<E> list = new ArrayList<>();
        for(E e:list){
            list.add(e);
        }
        return list;
    }
}

三、自定义泛型类例举

cpp 复制代码
package com.tyust.edu;

import java.util.List;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:55
 */
public class DAO<T> { //表的共性操作DAO

    //增删改查
    public  void add(T t){

    }
    public  boolean remove(int index){
        return false;
    }
    public void update(int index,T t){

    }
    public  T getIndex(int index){
        return null;
    }
    public List<T> getForList(int index){
        return null;
    }
    //泛型方法
    //举例:获取表中一共有多少条记录
    public  <E> E getValue(){
        return null;
    }
}
cpp 复制代码
package com.tyust.edu;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:58
 */
public class Customer {  //此类对应数据库中的customer表
}
cpp 复制代码
package com.tyust.edu;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 9:59
 */
public class CustomerDAO extends DAO<Customer>{  //只能操作某一个表的DAO
}
cpp 复制代码
package com.tyust.edu;

import org.junit.Test;

import java.util.List;

/**
 * @author YML TYUST-XDU 2019-2026
 * @create 2023-10-13 10:01
 */
public class DAOTest {
    @Test
    public  void test1(){
        CustomerDAO dao1 = new CustomerDAO();
        dao1.add(new Customer());
        List<Customer> list = dao1.getForList(10);
    }
}

四、泛型在继承方面的体现

1.泛型在继承方面的体现

类A是类B的父类,G<A>和G<B>不具备子父类关系,二者是并列关系
补充:类A是类B的父类,A<G>是B<G>的父类
cpp 复制代码
@Test
    public void test1(){
        Object obj = null;
        String str = null;
        obj = str;

        Object[] arr1 = null;
        String[] arr2 = null;
        arr1 = arr2;

        List<Object> list1 = null;
        List<String> list2 = null;
        //此时list1和list2不具备子父类关系
//        list1 = list2;

        //编译不通过
//        Date date = new Date();
//        str = date;




    }

    public void show(List<Object> list){

    }
    @Test
    public void test2(){
        AbstractList<String> list1 = null;
        List<String >list2 = null;
        ArrayList<String > list3 = null;
        list1 = list3;
        list2 = list3;
        List<String>list4 = new ArrayList<>();
    }

2.通配符的使用

通配符:?
类A是类B的父类,G <//A> 和G <//B> 是没有关系的,二者共同的父类是G<?>

cpp 复制代码
@Test
    public void test3(){
        List<Object> list1 = null;
        List<String >list2 = null;
        List<?>list = null;
        list = list1;
        list = list2;
        print(list1);
        print(list2);

        List <String >list3 = new ArrayList<>();
        list3.add("AA");
        list3.add("BB");
        list3.add("CC");
        list = list3;

        //添加 (写入):对于List<?>就不能向其内部添加数据
        //除了添加null之外
//        list.add("DD");
        list.add(null);

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

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

3.有限制条件的通配符的使用

? extends A :
G<?extends A>可以作为G<//A>和G<//B>的父类,其中B是A的子类
? super A:
G<? super A>可以作为G<//A>和G<//B>的父类,其中B是A的父类

cpp 复制代码
@Test
    public void test4(){
        List<? extends Person>list1 = null;
        List<? super Person>list2 = null;
        List<Student>list3 = new ArrayList<Student>();
        List<Person>list4 = new ArrayList<Person>();
        List<Object>list5 = new ArrayList<Object>();
        list1 = list3;
        list1 = list4;


        //读取数据
        list1 = list3;
        Person p = list1.get(0);

        list2.add(new Person());
        list2.add(new Student());


    }
相关推荐
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader1 小时前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭1 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0072 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生2 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
ssr——ssss2 小时前
SSM-期末项目 - 基于SSM的宠物信息管理系统
java·ssm
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言
鲤籽鲲2 小时前
C# Random 随机数 全面解析
android·java·c#
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring