【Java基础面试题033】Java泛型的作用是什么?

Java的基础语法可以看尚硅谷的这个PDF:尚硅谷JavaSE基础/《Java从入门到精通(JDK17版)》_尚硅谷电子书.pdf · Autism_Btkrsr/Blog_md_to_pdf - 码云 - 开源中国 (gitee.com)

回答重点

Java泛型的作用是通过在编译时检查类型安全,允许程序员编写更通用和灵活的代码,避免在运行时发生类型转换错误。

总结作用

  • **类型安全:**泛型允许在编译时进行类型检查,确保在使用集合或其他泛型类时,不会出现类型不匹配的问题,减少了运行时的ClassCastException错误
  • **代码重用:**泛型使代码可以适用于多种不同的类型,减少代码重复,提升可读性和可维护性
  • **消除显式类型转换:**泛型允许在编译时指定类型参数,从而消除了运行时需要显式类型转换的麻烦
java 复制代码
List<String> list = new ArrayList<>();
list.add("Hello");
String str = list.get(0); // 不需要类型转换

扩展知识

泛型的实际应用

  • **集合框架:**Java的集合框架广泛使用了泛型。List<T>、Set<T>和Map<K, V>等接口可以针对不同的数据类型实现统一的操作

  • **泛型方法:**不仅可以定义泛型类,还可以定义泛型方法,使得方法能够处理多种不同的数据类型

  • 泛型方法

可以显式指定类型,不指定的话,Java编译器会自动推断类型

java 复制代码
public class GenericMethodTest {
    public static void main(String[] args) {
        Integer[] intArr = {1, 2, 3, 4, 5};
        Double[] doubleArr = {1.1, 2.2, 3.3, 4.4, 5.5};
        String[] stringArr = {"Hello", "World"};
        printArray(intArr);
        // 显式指定类型
        GenericMethodTest.<Integer>printArray(intArr);
        printArray(doubleArr);
        printArray(stringArr);
        // 多类型参数
        new GenericMethodTest().printMultiArgsArray(intArr, stringArr);
    }
    public static <T> void printArray(T[] arr){
        for (T element: arr){
            System.out.print(element);
        }
        System.out.println();
    }
    // 多类型参数
    public <T, V> void printMultiArgsArray(T[] keys, V[] values){
        for (int i = 0; i < Math.min(keys.length, values.length); i++){
            System.out.printf("{Key:%s,Value:%s}\n", keys[i], values[i]);
        }
    }
}

为什么需要泛型?

在Java5之前是没有泛型的,没泛型都能用的好好的,为什么非要加个泛型呢?能解决什么问题呢?

看这段代码

java 复制代码
  List list = new ArrayList();
  list.add("yes"); // 加入string
  list.add(233); // 加入int

在没有泛型的时候,加入的集合的数据并不会做任何约束,都会被当做成Object类型。

可能有人说:这很好呀,多自由!确实,自由是挺自由,但是代码的约束力越低,越容易从出错,使用上也有诸多不便。比如获取的时候老是要强转

就算强转过了编译器这一关,运行的时候还是会报错

综上,Java就引入了泛型。

所以泛型的作用就是加了一层约束,约束了类型。

有了这一层约束就好办事了,由于声明了类型,可以在编译时就识别不出准确的类型元素。使得错误提早抛出,避免运行时才发现。

小结一下泛型的好处:

  • 提高了代码的可读性,一眼就能看出集合的类型
  • 可在编译期检查类型的安全,增加程序的健壮性
  • 省心不需要强转(其实内部帮做了强转,下面会说)
  • 提高代码的复用率,定义好泛型,一个方法(类)就能适配所有类型(其实以前Object也行,就是比较麻烦)

为什么Java的泛型是伪泛型?

java 复制代码
public class GenericReflectionTest {
    public static void main(String[] args) throws Exception{
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.getClass().getMethod("add", Object.class).invoke(list, 123);
        System.out.println(list);
    }
}

可以看到,我声明的是一个String类型的集合,但是通过反射往集合中插入了int类型的数据,居然成功了?

这说明在运行的时候泛型根本没起作用 !也就是说在运行的时候JVM获取不到泛型的信息,也不会对其做任何约束

可以认为Java的泛型就是编译时失效,运行的时候就是没有泛型,所以大家才说Java是伪泛型!

因此,实际上在运行的时候泛型的类型是被擦除

总结:Java的泛型只在编译时生效,JVM运行时没有泛型

关于反射的博客,看我这一篇:【Java】反射_反射 博客园-CSDN博客

相关推荐
Dream_Snowar4 分钟前
速通Python 第三节
开发语言·python
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭18 分钟前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫35 分钟前
泛型(2)
java
超爱吃士力架39 分钟前
邀请逻辑
java·linux·后端
南宫生44 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石1 小时前
12/21java基础
java
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
李小白661 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp1 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
信号处理学渣1 小时前
matlab画图,选择性显示legend标签
开发语言·matlab