一、泛型
- 允许在定义类和接口时使用类型参数
- 方便:提高代码复用性(一个List可以放String、Integer等多个类型,否则每个类型要单独写一个接口)
- 安全:在编译时做类型检查,不用则通过Object实现的类型转换要在运行时检查
- 实现方式:类型擦除(List<String> 变为List)【jvm感知不到泛型,只在编译期存在】
- 缺点:
- 不可重载
- 泛型异常类不可以多次catch
- 静态变量只有一份
泛型中上下界限定符extends vs super
- <? extends T> 表示上界参数化类型可能是T或T的子类
- <? super T> 表示下界参数化类型可能是T的超类型(父类,直到Object)
- 遵循“上界生产,下界消费”原则
- 如果要从集合读取类型T的数据且不能写入? extends
- 如果要从集合读取类型T的数据且不能读取? super
- 既读又写,不用通配符
二、泛型KTVE
- E:element(集合)
- T:Type(Java类)
- K:Key(键)
- V:Value(值)
- N:Number(数值类型)
- ?:不确定的java类型(无限制通配符)
- Object:所有类的根类
List<?> vs List<Object> vs List
- List<?>
- 未知类型
- List<String>可以赋给List<?>
- 由于不能确定列表中元素的具体类型,只可读,不能加元素(除了null)
- List<Object>
- 任意类型
- List<String>不能赋给List<Object>(产生编译错误:不支持协变)
- 协变(Covariance)
- 指能够安全地将一个更具体的类型视为一个更广泛的类型的能力
- 在面向对象编程中,通常意味着子类对象可以安全地被视为父类类型的对象
- 在Java的泛型中,协变并不直接适用到集合类型上,因为Java的泛型是不变的(invariant)
- 泛型不协变、数组协变(支持)
- 类似于Object是String的父类,但是对于两个泛型,他俩没有关系
- List
- 可以把任何带参数的类型传递给List
三、SPI vs API
- SPI
- 被框架扩展人员使用
- 扩展机制,在应用程序中提供可插拔的实现。调用方可以选择使用提供方的内置实现,也可以自己实现
- 应用场景
- 数据库驱动加载接口实现类的加载
- JDBC加载不同类型的数据库驱动
- 日志门面接口实现类加载
- SLF3J加载不同提供商的日志实现类
- Spring:ServletContainerInitializer、自动类型转换Type Conversion SPI
- API
- 被应用开发人员使用
- 定义了软件组件之间交互的规则和约定的接口,提供方制定接口并完成不同实现,调用方调用
四、反射
- 程序在运行时能获取自身信息
- 在运行时通过反射可以
- 判断任意一个对象所属的类
- 判断任意一个类所具有的成员变量和方法
- 任意调用一个对象的方法
- 任意构造一个类的对象
- 可读性低、可维护性低、执行性能低、破坏了封装性
- 为什么慢
- 设计动态解析的类型,不能执行某些java虚拟机优化(如JIT优化)
- 参数需要包装为Object[]类型,执行时再拆包。其过程中会产生很多对象,对象多就会GC(Garbage Collector,垃圾收集器 ),GC导致应用变慢
- 会从方法数组里遍历且检查可见性
- 参数也要检查
- 使用场景
- 动态代理
- JDBC的class.forName
- BeanUtils中属性值的拷贝
- RPC框架
- ORM框架
- Spring的IOC/DI
- 反射和class关系
- class类是反射机制的基础,通过class类获得关于一个类的信息
- 运行程序时,JVM首先检查是否所要加载的类对于的class对象已加载,没加载则根据类名查找.class文件并将其class对象载入
单例模式
- 把一个类的构造方法私有化,避免重复创建多个对象
- 使用反射、使用反序列化都可以破坏单例
- 改造构造函数:对象被创建过抛出错误
五、RPC、ORM、Spring的IOC/DI
-
RPC框架
- Remote Procedure Call,远程过程调用框架
- 一种用于实现远程调用的技术,它可以让不同的进程或计算机之间通过网络进行通信和调用远程方法
- 底层原理主要涉及通信协议、序列化和反序列化、网络传输、服务注册与发现等方面
- 主要特点、应用场景
- 分布式架构的核心:在分布式架构中,RPC框架用于解决各个服务之间的网络通信问题
- 跨语言远程调用:现代RPC框架基本实现了跨语言的远程调用,支持多种编程语言
- 优化设计:除了基础的远程通信功能外,RPC框架还会在系统性能、传输效率、服务治理等方面做出优化设计
- 流行的RPC框架
- Dubbo:阿里巴巴公司开源的高性能Java RPC框架,提供了完整的服务治理功能,支持多种协议和序列化方式,与Spring框架无缝集成
- gRPC:Google开源的跨语言RPC框架,基于HTTP/2协议和Protocol Buffers,性能高效,支持多种编程语言
- Thrift:Facebook开源的跨语言RPC框架,支持多种语言和数据格式,性能优秀。
-
ORM框架
- Object Relational Mapping,对象关系映射框架
- 一种采用元数据来描述对象与关系映射细节的框架
- 通过映射(反射)获取数据库的数据,使得开发者可以使用面向对象的方式来操作数据库
- 主要特点、作用
- 简化数据库操作:ORM框架提供了丰富的API和工具,使得开发者可以用面向对象的方式来操作数据库,而不是编写繁琐的SQL语句
- 提高开发效率:通过对象关系映射,ORM框架可以自动生成SQL语句,减少了开发者的重复性工作
- 支持多种数据库:大多数ORM框架都支持多种数据库,使得开发者可以在不同的数据库之间切换而不需要修改太多的代码
- 常见的ORM框架
- Hibernate:Hibernate是Java领域最流行的ORM框架之一,它提供了强大的数据持久化能力
- MyBatis:MyBatis是一个半自动化的ORM框架,它允许开发者编写自定义的SQL语句,并提供了丰富的映射功能
- iBatis:iBatis是MyBatis的前身,虽然现在已经不再维护,但在一些旧的项目中仍然可以看到它的身影
-
IOC(控制反转)
- IOC是一种设计思想,它将传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理
- IoC用于解耦,使得对象之间形成松散耦合,提高了系统的可维护性和可扩展性
- IoC容器负责创建对象,管理对象的生命周期,并根据配置文件或注解管理对象之间的依赖关系。
-
DI(依赖注入)
- DI是对IOC概念的不同角度描述,它是指在应用程序运行时,由IoC容器动态地将依赖关系注入到对象中
- DI主要有两种实现方式,即构造器注入和Setter方法注入。构造器注入是通过构造器来传递依赖对象,而Setter方法注入则是通过Setter方法来设置依赖对象。