1 minute read

Java 核心基础知识总结

本文档旨在总结Java语言的核心基础概念,作为学习和面试复习的参考。内容涵盖了从JVM到面向对象等关键知识点。


1. JDK, JRE, JVM 的关系

理解这三者的关系是学习Java的第一步。

  • JVM (Java Virtual Machine - Java虚拟机)
    • 它是一种规范,一个虚拟的计算机,负责执行Java字节码(.class文件)。
    • 它是Java实现“一次编译,到处运行”的核心
    • 不同的操作系统(Windows, macOS, Linux)有各自的JVM实现,从而屏蔽了底层操作系统的差异。
  • JRE (Java Runtime Environment - Java运行环境)
    • 它包含了 JVM 和Java程序运行所需的核心类库(如 java.lang, java.util 等)。
    • 如果只是想运行一个已经编译好的Java程序,那么只需要安装JRE即可。
  • JDK (Java Development Kit - Java开发工具包)
    • 它包含了 JRE 的所有内容,以及Java的开发工具
    • 主要工具包括:javac(编译器)、java(运行工具)、jdb(调试器)、javadoc(文档生成器)等。
    • 作为开发者,我们需要安装JDK来编写、编译和调试Java代码。

总结: JDK > JRE > JVM。JDK用于开发,JRE用于运行。


2. 为什么说 Java 是编译与解释共存的语言?

这个问题关联到Java程序的执行过程。

  1. 编译阶段:我们编写的 .java 源文件通过 javac 编译器,被编译成平台无关的 Java字节码(.class)文件。这是一个编译过程。

  2. 解释阶段:JVM启动时,解释器(Interpreter)会逐行读取.class文件,将其解释成对应平台的本地机器码并执行。这是一个解释过程。

  3. 即时编译 (JIT - Just-In-Time Compilation):如果仅仅是解释执行,效率会很低。因此,JVM引入了JIT编译器。它会在程序运行时,监测并识别出被频繁执行的“热点代码”(HotSpot),然后将这些热点代码一次性编译成高效的本地机器码,并缓存起来。后续再执行这些代码时,就会直接运行编译好的本地代码,而不是重新解释,从而极大地提升了执行效率。

结论:Java首先通过javac编译成字节码,然后JVM通过解释器解释执行,同时JIT编译器又会在运行时将热点代码编译成机器码。因此,Java是编译与解释共存的语言。


3. Java 的面向对象(OOP)三大特征

  • 封装 (Encapsulation)
    • 将类的实现细节(属性、方法)隐藏起来,只对外暴露有限的、安全的访问接口。
    • 优点:提高代码的安全性和可维护性。
    • 实现方式:使用 private 等访问修饰符限制直接访问,通过 publicgetter/setter 方法来访问。
  • 继承 (Inheritance)
    • 子类可以继承父类的属性和方法(非私有的),并可以进行扩展。
    • 优点:实现了代码的复用,建立了类之间的层次关系 (is-a)。
    • 实现方式:使用 extends 关键字。Java只支持单继承,即一个类只能有一个直接父类。
  • 多态 (Polymorphism)
    • 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
    • 优点:提高了代码的灵活性和可扩展性。
    • 实现前提
      1. 有继承/实现关系。
      2. 有方法重写(Override)。
      3. 有父类引用指向子类对象 (Parent p = new Child();)。

4. ==equals() 的区别

  • ==
    • 比较基本数据类型:比较的是是否相等。
    • 比较引用数据类型:比较的是两个对象的内存地址是否相同,即是否指向同一个对象。
  • equals()
    • Object 类中的一个方法,默认实现与 == 相同,也是比较内存地址。
    • 通常,像 String, Integer 等类会重写 (Override) equals() 方法,将其逻辑改为比较两个对象的内容是否相等。
    • 规范:当我们重写 equals() 方法时,通常也必须重写 hashCode() 方法,以保证 equals 相等的两个对象它们的 hashCode 也相等。这在 HashMap 等集合中至关重要。

5. String 的不变性 (Immutability)

String 对象一旦被创建,其内容(字符序列)就不能被改变。任何对 String 对象的修改操作(如拼接、替换)实际上都会创建一个新的 String 对象。

为什么这样设计?

  1. 线程安全:因为不可变,所以可以在多线程环境中被安全地共享,无需任何同步操作。
  2. 可用于缓存:Java中存在一个字符串常量池 (String Pool)。当创建一个字符串时,JVM会先在池中查找是否存在内容相同的字符串,如果存在,则直接返回池中的引用,避免重复创建。不变性是实现字符串常量池的基础。
  3. 安全性:在网络连接、数据库连接等场景中,传入的参数是字符串,其不可变性防止了在后续操作中被意外篡改。

相关类对比

  • StringBuilder:可变字符串,用于单线程环境下的字符串拼接,效率高。
  • StringBuffer:可变的线程安全字符串,用于多线程环境,方法被 synchronized 修饰,效率低于 StringBuilder

6. 抽象类 (Abstract Class) 与 接口 (Interface) 的区别

特性 抽象类 (abstract class) 接口 (interface)
继承/实现 子类使用 extends 继承,单继承 实现类使用 implements 实现,可实现多个接口
构造方法 构造方法(用于子类实例化时调用) 没有构造方法
成员变量 可以有各种类型的成员变量(实例变量、静态变量) 只能有 public static final 的常量(可省略修饰符)
成员方法 可以有抽象方法,也可以有具体的普通方法 JDK 8前只能有抽象方法;JDK 8后可包含 defaultstatic 方法
设计理念 表示一种 “is-a” 的关系,强调所属关系,是对“一类事物”的抽象 表示一种 “can-do” 的关系,强调能力和行为规范,是对“行为”的抽象