六、泛型
1. 什么是泛型?
泛型是Java编程语言中的一个重要特性,它允许类、接口和方法在定义时使用一个或多个类型参数,这些类型参数在使用时可以被指定为具体的类型。
泛型的主要目的是在编译时提供更强的类型检查,并且在编译后能够保留类型信息,避免在运行时出现类型转换异常。
2. 为什么需要泛型
适用于多种数据类型执行相同的代码
泛型中的类型在使用时指定,不需要强制类型转换
七、对象
1. Java创建对象有哪些方式?
-
使用
new关键字:通过调用类的构造器来实例化对象 -
使用
Class类的newInstance()方法 -
使用
Constructor类的newInstance()方法 -
使用
clone方法,实现Cloneable接口并重写clone()方法 -
使用反序列化
-
使用工厂模式,通过方法来返回对象实例
2. 如何获取私有对象?
-
通过类内部提供的
get方法 -
通过反射
八、反射
1. 什么是反射?
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息和动态调用对象的方法的功能就称为反射。
2.反射在你平时写代码或者框架中的应用场景有哪些?
-
加载数据库驱动
-
配置文件加载:
-
Spring框架的IOC,Spring通过配置文件配置各种各样的bean,需要用到哪些bean就配置哪些,Spring容器会根据需求去动态加载
-
过程:
-
将程序中所有xml或者properties配置文件加载进内存
-
Java类里面解析配置文件内容,得到对应实体类字节码字符串和相关的属性信息
-
使用反射机制,根据字符串获得某个类的Class实例
-
动态配置实例的属性
-
-
九、Object
1. Object类有哪些方法?
equals方法:
-
重写
equals方法必须重写hashCode方法,因为Java的约定是如果两个对象equals返回true,它们的hashCode必须相等;如果hashCode不相等,equals一定返回false -
如果只重写
equals不重写hashCode,会导致对象在HashMap等集合中无法正确存储,比如两个id相同的User对象,equals返回true,但hashCode不同,会被当成两个不同元素存入集合
toString方法:
-
默认是返回类名加
@加对象的哈希码十六进制表示 -
一般重写来返回对象的具体信息
getClass方法:
- 返回对象运行时的实际类对象
clone方法:
- 用于创建对象的浅拷贝
notify和notifyAll:
-
用于多线程同步,和
synchronized配合使用 -
作用是唤醒当前对象锁的进程
wait方法有三个重载:
-
作用是让当前持有对象锁的线程释放锁并进入等待状态
-
直到被
notify/notifyAll唤醒或者等待时间到期
finalize方法:
-
对象被垃圾回收器回收前会调用的方法
-
默认是空实现
2. 字符串常量池
当直接用双引号创建字符串的时候,JVM会把它扔到一个叫"字符串常量池"的地方。如果池子里已经有了这个字符串,那么新创建的字符串就会直接复用常量池中的字符串,所以他俩地址是一样的,==会返回true。
3. String、StringBuffer、StringBuilder的区别和联系
可变性:
-
String是不可变的,一旦创建,内容无法修改,每次修改都会生成一个新的对象 -
StringBuilder和StringBuffer是可变的,可以直接对字符串内容进行修改而不会创建新对象
线程安全性:
-
String因为不可变,天然线程安全 -
StringBuilder不是线程安全的,适用于单线程环境 -
StringBuffer是线程安全的,其方法通过synchronized关键字实现同步,适用于多线程环境
性能:
-
String性能最低,尤其是在频繁修改字符串时会生成大量临时对象,增加内存开销和垃圾回收压力 -
StringBuilder性能最高,因为它没有线程安全的开销,适合单线程下的字符串操作 -
StringBuffer性能略低于StringBuilder,因为它的线程安全机制引入了同步开销
使用场景:
-
如果字符串内容固定或不常变化,优先使用
String -
如果需要频繁修改字符串并且在单线程使用,用
StringBuilder -
如果需要频繁修改字符串并且在多线程环境下,使用
StringBuffer
十、序列化
1. 怎么把一个对象从一个JVM转移到另一个JVM?
-
使用序列化和反序列化:
-
将对象序列化为字节流,并将其发送给另一个JVM
-
然后在另一个JVM中反序列化字节流恢复对象
-
-
使用消息传递机制:
-
利用消息传递机制,比如使用消息队列(RabbitMQ、Kafka)或者通过网络套接字进行通信
-
将对象从一个JVM发送到另一个JVM
-
-
使用远程方法调用(RPC):
- 可以使用远程方法调用框架,如gRPC,来实现对象在不同JVM之间的传输
-
使用共享数据库或缓存:
-
将对象存储在共享数据库(MySQL)或共享缓存(Redis)
-
让不同的JVM可以访问这些共享数据
-
2. 序列化和反序列化让你自己实现你会怎么做?
考虑主流序列化框架,比如FastJson、Protobuf来替代Java序列化。