【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博客

相关推荐
数据潜水员1 小时前
C#基础语法
java·jvm·算法
明月看潮生1 小时前
青少年编程与数学 02-020 C#程序设计基础 15课题、异常处理
开发语言·青少年编程·c#·编程与数学
你这个代码我看不懂2 小时前
Java项目OOM排查
java·开发语言
暴力求解2 小时前
C语言---动态内存管理、柔性数组
c语言·开发语言·算法
Zong_09152 小时前
AutoCompose - 携程自动编排【开源】
java·spring boot·开源·自动编排
先做个垃圾出来………2 小时前
Python中使用pandas
开发语言·python·pandas
DanmF--2 小时前
C#面向对象实践项目--贪吃蛇
开发语言·游戏·c#·游戏程序
@老蝴2 小时前
C语言 — 动态内存管理
android·c语言·开发语言
.生产的驴2 小时前
SpringCloud 分布式锁Redisson锁的重入性与看门狗机制 高并发 可重入
java·分布式·后端·spring·spring cloud·信息可视化·tomcat
虾球xz3 小时前
CppCon 2014 学习:C++ Memory Model Meets High-Update-Rate Data Structures
java·开发语言·c++·学习