21
【Q】: 什么是Java的SPI机制?
【A】:
- SPI 是一种插件机制,用于在运行时动态加载服务的实现。它通过定义接口(服务接口)并提供一种可扩展的方式来让服务的提供着(实现类)在运行时注入,实现解耦和模块化设计。
- SPI机制的核心概念:
- 服务接口:接口或抽象类,定义某个服务的规范或功能。
- 服务提供者:实现了服务接口的具体实现类。
- 服务加载器:Java提供的工具类,负载动态加载服务的实现类。提供ServiceLoader可以在运行时发现和加载多个服务提供者。
- 配置文件:服务提供者通过在META-INF/services/目录下配置服务接口的文件来声明自己。这些文件的内容是实现该接口的类的完全限定名。
- SPI机制的优势:
- 解耦:接口与实现分类,客户端不需要依赖具体实现,能够在运行时灵活加载不同的实现类。
- 可扩展性:提供了一种易于扩展的机制,允许后期添加或替换实现类,而不需要修改现有的代码。
22
【Q】:Java泛型的作用是什么?
【A】:
- Java泛型的作业是通过编译时检查类型安全,允许程序员编写更通用和灵活的代码,避免在运行时发现类型转换错误。
- 作用:
- 类型安全:泛型运行在编译时进行类型检查,确保在使用集合或者其他泛型类时,不会出现类型不匹配的问题,减少了运行时的
ClassCastException
错误。 - 代码重用:泛型使代码可以适用于多种不同的类型,减少代码重复,提升可读性和维护性。
- 消除显式类型转换:泛型允许在编译时指定类型参数,从而消除了运行时需要显示类型转换的麻烦。
- 类型安全:泛型运行在编译时进行类型检查,确保在使用集合或者其他泛型类时,不会出现类型不匹配的问题,减少了运行时的
23
【Q】:Java泛型擦除是什么?
【A】:
- 泛型擦除指Java编译时将所有泛型信息删除的过程,以确保与Java1.4之前的版本保存兼容。泛型参数在运行时会被替换为其上界(通常是Object),这样一来在运行时无法获取的实际类型。
- 作用:泛型擦除确保了Java代码的向后兼容性,但它也限制了在运行时对泛型类型的操作。
- 运行:由于类型擦除,无法在运行时获取泛型的实际类型,也不能创建泛型类型的数组或对泛型类型使用 。
24
【Q】:什么是Java泛型的上下界限定符?
【A】:
- 用于对泛型类型参数进行范围限制,主要有上界限定符和下界限定符。
- 上界限定符(?extends T):
?extends
T表示通配符类型必须是T类型或T类型的子类。允许使用T或其子类型作为泛型参数,通常用于读取操作,确保可以读取为T或T的子类的对象。 - 下界限定符(?super T):?super T表示通配符类型必须是T类型或T类型的父类。允许使用T或其父类型作为泛型参数,通常用于写入操作,确保可以安全地向泛型集合中插入T类型的对象。
25
【Q】:Java中的深拷贝和浅拷贝有什么区别?
【A】:
- 深拷贝:不复制对象本身,还递归复制对象中所有引用的对象。这样新的对象与原对象完全独立。
- 浅拷贝:只复制对象的引用,而不复制引用指向的实际对象。浅拷贝创建一个新的对象,但它的字段(若是对象类型)指向的是原对象中的相同内存引用。
26
【Q】:什么是Java的Integer缓存池?
【A】:
- Java的
Integer
缓存池:为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围,因为缓存这些对象可以减少内存的分配和垃圾回收的负担,提升性能。 - 在
-128
~127
范围内的Integer
对象会被缓存和复用。 - Java在自动装箱时,对于值在
-128
~127
之间的int
类型,会直接返回一个已经缓存的integer
对象,而不是创建新的对象。 - 缓存池的使用场景:当基本数据类型
int
转化为包装类型Integer
时,若数值在缓存范围内,返回缓存对象;由于相同范围内的整数使用同一个缓存对象,使用==
可以正确比较它们的地址(引用相同),而不需要使用equals
。但是要注意对于超过范围的Integer
对象,==
比较的是对象引用,而不是数值。要比较数值,应使用equals
方法。
27
【Q】:Java中的类加载过程是怎么样的?
【A】:
- 是把类加载到JVM中,把二进制流存储到内存中,之后经过一番解析、处理转化成可用的class类。二进制流可用来源于class文件,或通过字节码工具生成的字节码或来自网络。只要符合格式的二进制流,JVM来着不拒。
- 类加载流程分为:加载、连接(验证、准备、解析)、初始化。
28
【Q】:什么是Java中的BigDecimal?
【A】:
- 是Java中提供的一个用于高精度计算的类,属于java.math包。对浮点数和定点数的精确控制。
- 高精度:可以处理任何精度的数值,而不像float和double存在限制。
- 不可变性:所有算术运算都会返回新的BigDecimal对象,而不会改原有对象。
- 丰富的功能:提供了较多方法,支持各种舍入模式。
29
【Q】:BigDecimal为什么可以保证精度不丢失?
【A】:
- 使用了任意进度的整数表示伐,而不是浮动的二进制表示,
- 内部使用两个字段存储数字,一个是整数部分
intVal
,另一个是用来表示小数点的位置scale
,避免了浮点数转化过程中可能的精度丢失。
30
【Q】:new String(“”)会创建多少个对象?
【A】:
- 会创建1个或2个字符串对象。
- 如果字符串常量池中不存在对象的引用,那么它会在堆上创建两个字符串对象,其中一个字符串对象的引用会被保存在字符串常量池中。