【java】泛型与Object的区别,如何在实际场景中选择泛型以及Object

简介

本文介绍泛型与Object的区别,如何在实际场景中选择泛型以及Object

什么是泛型

以下内容来自菜鸟教程:

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是可以使用 Java 泛型。
使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。

java 中泛型标记符:

E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的 java 类型

其实 A-Z都可以作为泛型标记符,上面只是一种约定,增强代码的可读性,方便团队间的合作开发

泛型的作用

  1. 将运行时出现的错误提前到了编译时

  2. 避免了类型强转的麻烦

泛型与Object类有什么区别

主要是使用的时机不同

  • 泛型:如果我确定要用哪个对象,并且使用到这个对象里面的属性,选择用泛型,因为泛型代表着更精确的对象,能够使用独有的方法。

  • Object类:Object是所有类的父类,特别笼统,且只能使用固定的属性。只要有Object的地方,基本都能用泛型替代。

实际场景中该如何选择泛型

案例1、创建泛型类

其实这个例子很常见,在java源码中就有不少案例,比如常见的一些集合类

在这里插入图片描述

因为java在让开发者使用的时候是不知道我们要传入的类型的,而使用Object的话就需要开发者自己强转,可能会发生类型转换异常

案例2、使用泛型定义工具类(解决缓存穿透)

同样的道理,我们如果想自定义工具类给别人使用就要使用泛型,因为我们不确定使用者要传入的类型是哪些。

/**
     * 缓存穿透
     * @param keyPrefix key的前缀
     * @param id    id
     * @param type  返回值类型
     * @param dbFallback    函数
     * @param time  时间
     * @param unit  单位
     * @return
     * @param <T>   类型的泛型
     * @param <ID>  id的泛型
     */
    public <T,ID> T queryWithPassThrough(String keyPrefix, ID id , Class<T> type, Function<ID, T> dbFallback, Long time, TimeUnit unit){
    
    
        String key = keyPrefix + id;
        // 1.从redis查询商铺缓存(以string类型为例)
        String json = stringRedisTemplate.opsForValue().get(key);
        // 2.判断是否存在
        if(StrUtil.isNotBlank(json)){
    
    
            // 3.存在,直接返回
            return JSONUtil.toBean(json, type);
        }

        // 判断命中的是否是空值
        if (json != null){
    
    
            return null;
        }

        // 4.不存在,根据id查询数据库
        T t = dbFallback.apply(id);

        // 5.不存在,返回错误
        if (r == null){
    
    
            // 将空值写入redis
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
            return null;
        }

        // 6.存在,写入redis
        this.set(key, t, time, unit);

        // 7.返回
        return t;
    }

案例3、集合类使用不确定泛型"<?>"

这里要使用不确定泛型来接收集合类

    public String export(ArrayList<?> arrayList, Class<?> excelVO, String sheetName) {
    
    
        String fileName = System.currentTimeMillis() + XLSX;
        EasyExcel.write(fileName, excelVO).sheet(sheetName).doWrite(arrayList);
        return fileName;
    }

猜你喜欢

转载自blog.csdn.net/qq_51383106/article/details/131783620