java 基础
Java 核心基础知识总结
本文档旨在总结Java语言的核心基础概念,作为学习和面试复习的参考。内容涵盖了从JVM到面向对象等关键知识点。
1. JDK, JRE, JVM 的关系
理解这三者的关系是学习Java的第一步。
- JVM (Java Virtual Machine - Java虚拟机)
- 它是一种规范,一个虚拟的计算机,负责执行Java字节码(
.class文件)。 - 它是Java实现“一次编译,到处运行”的核心。
- 不同的操作系统(Windows, macOS, Linux)有各自的JVM实现,从而屏蔽了底层操作系统的差异。
- 它是一种规范,一个虚拟的计算机,负责执行Java字节码(
- JRE (Java Runtime Environment - Java运行环境)
- 它包含了 JVM 和Java程序运行所需的核心类库(如
java.lang,java.util等)。 - 如果只是想运行一个已经编译好的Java程序,那么只需要安装JRE即可。
- 它包含了 JVM 和Java程序运行所需的核心类库(如
- JDK (Java Development Kit - Java开发工具包)
- 它包含了 JRE 的所有内容,以及Java的开发工具。
- 主要工具包括:
javac(编译器)、java(运行工具)、jdb(调试器)、javadoc(文档生成器)等。 - 作为开发者,我们需要安装JDK来编写、编译和调试Java代码。
总结: JDK > JRE > JVM。JDK用于开发,JRE用于运行。
2. 为什么说 Java 是编译与解释共存的语言?
这个问题关联到Java程序的执行过程。
-
编译阶段:我们编写的
.java源文件通过javac编译器,被编译成平台无关的 Java字节码(.class)文件。这是一个编译过程。 -
解释阶段:JVM启动时,解释器(Interpreter)会逐行读取
.class文件,将其解释成对应平台的本地机器码并执行。这是一个解释过程。 -
即时编译 (JIT - Just-In-Time Compilation):如果仅仅是解释执行,效率会很低。因此,JVM引入了JIT编译器。它会在程序运行时,监测并识别出被频繁执行的“热点代码”(HotSpot),然后将这些热点代码一次性编译成高效的本地机器码,并缓存起来。后续再执行这些代码时,就会直接运行编译好的本地代码,而不是重新解释,从而极大地提升了执行效率。
结论:Java首先通过javac编译成字节码,然后JVM通过解释器解释执行,同时JIT编译器又会在运行时将热点代码编译成机器码。因此,Java是编译与解释共存的语言。
3. Java 的面向对象(OOP)三大特征
- 封装 (Encapsulation)
- 将类的实现细节(属性、方法)隐藏起来,只对外暴露有限的、安全的访问接口。
- 优点:提高代码的安全性和可维护性。
- 实现方式:使用
private等访问修饰符限制直接访问,通过public的getter/setter方法来访问。
- 继承 (Inheritance)
- 子类可以继承父类的属性和方法(非私有的),并可以进行扩展。
- 优点:实现了代码的复用,建立了类之间的层次关系 (
is-a)。 - 实现方式:使用
extends关键字。Java只支持单继承,即一个类只能有一个直接父类。
- 多态 (Polymorphism)
- 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
- 优点:提高了代码的灵活性和可扩展性。
- 实现前提:
- 有继承/实现关系。
- 有方法重写(Override)。
- 有父类引用指向子类对象 (
Parent p = new Child();)。
4. == 与 equals() 的区别
==- 比较基本数据类型:比较的是值是否相等。
- 比较引用数据类型:比较的是两个对象的内存地址是否相同,即是否指向同一个对象。
equals()- 是
Object类中的一个方法,默认实现与==相同,也是比较内存地址。 - 通常,像
String,Integer等类会重写 (Override)equals()方法,将其逻辑改为比较两个对象的内容是否相等。 - 规范:当我们重写
equals()方法时,通常也必须重写hashCode()方法,以保证equals相等的两个对象它们的hashCode也相等。这在HashMap等集合中至关重要。
- 是
5. String 的不变性 (Immutability)
String 对象一旦被创建,其内容(字符序列)就不能被改变。任何对 String 对象的修改操作(如拼接、替换)实际上都会创建一个新的 String 对象。
为什么这样设计?
- 线程安全:因为不可变,所以可以在多线程环境中被安全地共享,无需任何同步操作。
- 可用于缓存:Java中存在一个字符串常量池 (String Pool)。当创建一个字符串时,JVM会先在池中查找是否存在内容相同的字符串,如果存在,则直接返回池中的引用,避免重复创建。不变性是实现字符串常量池的基础。
- 安全性:在网络连接、数据库连接等场景中,传入的参数是字符串,其不可变性防止了在后续操作中被意外篡改。
相关类对比:
StringBuilder:可变字符串,用于单线程环境下的字符串拼接,效率高。StringBuffer:可变的线程安全字符串,用于多线程环境,方法被synchronized修饰,效率低于StringBuilder。
6. 抽象类 (Abstract Class) 与 接口 (Interface) 的区别
| 特性 | 抽象类 (abstract class) |
接口 (interface) |
|---|---|---|
| 继承/实现 | 子类使用 extends 继承,单继承 |
实现类使用 implements 实现,可实现多个接口 |
| 构造方法 | 有构造方法(用于子类实例化时调用) | 没有构造方法 |
| 成员变量 | 可以有各种类型的成员变量(实例变量、静态变量) | 只能有 public static final 的常量(可省略修饰符) |
| 成员方法 | 可以有抽象方法,也可以有具体的普通方法 | JDK 8前只能有抽象方法;JDK 8后可包含 default 和 static 方法 |
| 设计理念 | 表示一种 “is-a” 的关系,强调所属关系,是对“一类事物”的抽象 | 表示一种 “can-do” 的关系,强调能力和行为规范,是对“行为”的抽象 |