3.2.8 String 为什么是不可变的? 另外,StringBuffer 和 StringBuilder 的区别是什么?

【考点映射】
  • Java 数据类型
【出现频度】★★★★
【难度】★★★

【参考答案】
在 Java8 中,String 类中用 final 关键字来修饰字符数组来保存字符串(private final char value[]),所以 String对象是不可变的,同时 String对象 也是线程安全的。
首先先来谈谈 StringBuffer 和 StringBuilder 的相同点,再去对区别做解释。
StringBuffer 和 StringBuilder 都继承自 AbstractStringBuilder 类,而 AbstractStringBuilder 用字符数组保存字符串(char[] value),但是没有用final关键字修饰,所以StringBuffer和StringBuilder都是可变的。
AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。
StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。
StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。同等情况下,使用 StringBuilder 相比使用 StringBuffer 性能提升不是特别大,但却要冒多线程不安全的风险。
总结:
  1. 操作少量的数据: 适用 String
  2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
  3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer


3.2.9 对Java的反射机制了解么?简单介绍一下。

【考点映射】
  • Java 反射
【出现频度】★★★★
【难度】★★☆

【参考答案】
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。
反射机制具有以下功能
  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。
反射机制和字节码文件(.class)的关系:
对于一个字节码文件.class,虽然表面上我们对该字节码文件一无所知,但该文件本身却记录了许多信息。Java在将.class字节码文件载入时,JVM将产生一个java.lang.Class对象代表该.class字节码文件,从该Class对象中可以获得类的许多基本信息,这就是反射机制。
反射机制所需的类主要有java.lang包中的Class类和java.lang.reflect包中的Constructor类、Field类、Method类和Parameter类。其中,Class类是一个比较特殊的类,它是反射机制的基础。
关于Class类的一些操作:
反射机制的优缺点:
  • 优点: 运行时可以对类型进行判断,动态加载类,动态调用一个对象的方法,提高代码灵活度。
  • 缺点: 从性能上来看,反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的 java 代码要慢很多。从安全性来看,让我们可以动态操作改变类的属性同时也增加了类的安全隐患。
反射的实际运用场景举例:
  1. 我们在使用 JDBC 连接数据库时使用 Class.forName() 通过反射加载数据库的驱动程序;
  2. Spring 框架的 IOC(动态加载管理 Bean)创建对象以及 AOP(动态代理)功能都和反射有联系;
  3. 动态配置实例的属性


3.2.10 对Java的泛型了解么?简单介绍一下。

【考点映射】
  • Java 泛型
【出现频度】★★★☆
【难度】★★☆

【参考答案】
Java 泛型(generics)是 JDK 5 中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法
语法格式:
泛型类:
定义泛型类:
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{