Java的特点
文章目录
- Java的特点
-
-
- [一、说一下 Java 的特点](#一、说一下 Java 的特点)
- [二、Java 的优势和劣势是什么?](#二、Java 的优势和劣势是什么?)
- [三、Java 为什么是跨平台的?](#三、Java 为什么是跨平台的?)
- [四、JVM、JDK、JRE 三者关系?](#四、JVM、JDK、JRE 三者关系?)
- [五、JVM 和 Java 有什么区别?](#五、JVM 和 Java 有什么区别?)
- [六、为什么 Java 解释和编译都有?](#六、为什么 Java 解释和编译都有?)
- [七、JVM 是什么?](#七、JVM 是什么?)
- 八、编译型语言和解释型语言的区别?
- [九、Python 和 Java 区别是什么?](#九、Python 和 Java 区别是什么?)
- 值传递和引用传递的区别?
-
一、说一下 Java 的特点
主要有以下特点:
- 平台无关性: Java 的"编写一次,运行无处不在"哲学是其最大特点之一。Java 编译器将源代码编译成字节码(bytecode),该字节码可以在任何安装了 Java 虚拟机(JVM)的系统上运行。
- 面向对象: Java 是一门严格的面向对象编程语言,几乎一切都是对象。面向对象编程(OOP)特性使代码更易于维护和重用,包括类(class)、对象(object)、继承(inheritance)、多态(polymorphism)、抽象(abstraction)和封装(encapsulation)。
- 内存管理: Java 有自己的垃圾回收机制,自动管理内存和回收不再使用的对象。开发者不需要手动管理内存,从而减少内存泄漏和其他内存相关问题。
二、Java 的优势和劣势是什么?
Java 的优势包括:
- 跨平台:因为 JVM 的存在,可一次编写、到处运行。
- 面向对象:Java 从设计之初就是 OOP 语言。
- 强大的生态系统:Spring、Hibernate 等框架,以及丰富的库、工具和社区支持,企业应用广泛。
- 自动垃圾回收:减少内存泄漏问题,对开发者友好。
- 多线程支持:内置线程机制,便于并发编程。
- 安全性:有安全模型,例如沙箱机制,适合网络环境。
- 稳定性:企业级应用长期使用,版本更新较注重向后兼容。
劣势包括:
- 性能开销:虽然 JVM 优化很多,但相比 C++、Rust 等原生编译语言仍有一定开销。
- 启动时间:例如微服务场景下,可能不如 Go 等语言快。
- 语法较繁琐:样板代码较多;虽已引入 Lambda,但相比 Python 仍不够简洁。
- 内存消耗:JVM 本身需要占用内存,对资源有限的环境不够友好。
- 面向对象较严格:写简单程序时有时反而麻烦;Java 8 引入函数式编程,但不如其他语言自然。
- 开发效率:相比 Python 等动态语言,Java 需要更多代码,编译过程也可能拖慢开发节奏。
三、Java 为什么是跨平台的?
Java 能支持跨平台,主要依赖 JVM。
JVM 也是软件,不同平台有不同版本。Java 源码编译后会生成 .class 文件,称为字节码文件。Java 虚拟机负责将字节码文件翻译成特定平台下的机器码并运行。不同平台只要安装对应 JVM,就可以运行字节码文件和 Java 程序。
Java 程序本身不需要改变,只通过 JVM 这个"中间层"就能在不同平台运行,实现"一次编译,到处运行"。JVM 是桥梁,是实现跨平台的关键:Java 代码先编译为字节码文件,再由 JVM 将字节码翻译成机器语言,从而运行程序。
编译结果不是机器码,而是字节码。字节码不能直接运行,必须通过 JVM 翻译成机器码。不同平台下编译生成的字节码相同,但 JVM 翻译生成的机器码不同。
因此运行 Java 程序必须有 JVM 支持。即使将 Java 程序打包为可执行文件(例如 .exe),通常仍需要 JVM 支持。
跨平台的是 Java 程序,不是 JVM。JVM 使用 C/C++ 开发,属于平台相关的软件,不同平台需要安装不同版本的 JVM。

四、JVM、JDK、JRE 三者关系?

- JVM(Java Virtual Machine): Java 虚拟机,是 Java 程序运行的环境。负责将 Java 字节码(由 Java 编译器生成)解释或编译成机器码并执行程序;也提供内存管理、垃圾回收和安全性等功能,使 Java 程序具备跨平台性。
- JDK(Java Development Kit): Java 开发工具包,是开发 Java 程序所需的工具集合。包含 JVM、编译器(
javac)、调试器(jdb)等开发工具,以及一系列类库。JDK 提供开发、编译、调试和运行 Java 程序所需的全部工具和环境。 - JRE(Java Runtime Environment): Java 运行时环境,是运行 Java 程序所需的最小环境。包含 JVM 和一组 Java 类库,用于支持 Java 程序执行;JRE 不包含开发工具,只提供运行环境。
五、JVM 和 Java 有什么区别?
Java 是语言,JVM 是平台:一个用于写代码,一个用于运行代码,两者分工不同但相互配合。
Java 是平时编写代码使用的编程语言,String、List 等都是 Java 语言提供的。JVM 全称 Java 虚拟机,是用来运行 Java 程序的平台或运行环境。

可以类比为:Java 像写文章使用的中文;JVM 像能够阅读和理解文章的人。Java 代码不能直接运行,需要先被编译器编译为字节码,即 .class 文件;再由 JVM 将字节码翻译成机器能理解的指令执行。
Java 的跨平台能力主要由 JVM 提供。Java 代码编译后的字节码可在 Windows、Linux、macOS 的 JVM 上运行。JVM 屏蔽底层操作系统差异,完成适配。因此本质是 JVM 依赖平台,Java 字节码不依赖平台。

JDK 是开发工具包,包含编译器、调试工具等,也包含 JRE;JRE 是运行环境,包含 JVM 和 Java 核心类库。关系为:
text
JDK ⊇ JRE ⊇ JVM
开发 Java 程序需要安装 JDK;传统理解中,若只运行别人写好的程序,安装 JRE 即可。

JVM 不只能运行 Java。JVM 执行的是字节码,Kotlin、Scala 等语言编译后也能生成 Java 字节码,因此同样可以在 JVM 上运行。JVM 已成为整个 JVM 语言生态的基础平台。
六、为什么 Java 解释和编译都有?
Java 源代码经编译后生成字节码文件,接着进入 JVM 后会经历解释和编译两个环节。

编译:
Java 源代码先由 javac 编译为平台无关的字节码(.class)文件,这一步发生在程序运行之前。
解释 / JIT:
JVM 启动后先由解释器逐条解释执行字节码;同时 JVM 通过方法调用计数器和回边计数器识别热点代码,达到阈值后由 JIT 编译为本地机器码,并缓存到 Code Cache 中,后续执行直接使用机器码。
所以 Java 同时具有编译型与解释型语言的特点,默认采用解释器和编译器混合的模式。
七、JVM 是什么?
JVM 是 Java 虚拟机,主要工作是解释自己的指令集(即字节码),并映射到本地 CPU 指令集和操作系统的系统调用。
JVM 屏蔽与操作系统平台相关的信息,使 Java 程序只需要生成在 Java 虚拟机上运行的目标代码(字节码),即可在多种平台上不加修改地运行。这也是 Java 能够"一次编译,到处运行"的原因。
八、编译型语言和解释型语言的区别?
- 编译型语言: 程序执行前,整个源代码被编译成目标平台的机器码,生成可执行文件。执行时直接运行编译后的代码,速度快,但跨平台性较差。Java 这种"先编译为字节码,再由虚拟机解释 / JIT 执行"的模式,严格说属于编译型与解释型的混合。
- 解释型语言: 程序执行时逐行解释执行源代码,不生成独立可执行文件。通常由解释器动态解释并执行,跨平台性好,但执行速度相对较慢。
典型编译型语言有 C、C++;典型解释型语言有 Python、JavaScript。
九、Python 和 Java 区别是什么?
- Java 是编译与解释混合执行的语言:源代码先由
javac编译成字节码(.class),再由 JVM 加载,通过解释器 + JIT 即时编译器执行。 - Python 是解释型语言:运行时由解释器逐行翻译并执行源代码。CPython 内部也会先编译为字节码
.pyc,但整体执行模型仍以解释执行为主。
值传递和引用传递的区别?
Java 中参数传递只有值传递一种方式,不存在真正的"引用传递"。核心区别在于传递的是"值的副本"还是"引用的副本"。
值传递(Pass by Value): 传递实际值的副本,适用于 int、char 等基本数据类型。修改方法内的参数副本,不会影响原变量。
java
public static void main(String[] args) {
int num = 10;
changeValue(num);
System.out.println(num); // 输出 10(原变量未被修改)
}
public static void changeValue(int a) {
a = 20; // 仅修改副本
}
对引用传递的常见误解: 对象属于引用类型,但传入方法的仍是对象引用的副本,而非对象本身。原引用和副本指向同一个对象,因此通过副本修改对象内部数据会影响原对象;但重新给副本赋值、改变副本指向,不会影响原引用指向。
java
public class Person {
String name;
Person(String name) { this.name = name; }
}
public static void main(String[] args) {
Person p = new Person("Alice");
changeName(p);
System.out.println(p.name); // 输出 "Bob"(对象内部被修改)
changeReference(p);
System.out.println(p.name); // 仍输出 "Bob"(原引用指向未变)
}
// 修改对象内部数据
public static void changeName(Person obj) {
obj.name = "Bob"; // 副本和原引用指向同一个对象
}
// 修改副本的指向(不影响原引用)
public static void changeReference(Person obj) {
obj = new Person("Charlie"); // 副本指向新对象,原引用仍指向旧对象
}
简单来说,Java 中所有参数传递都是值传递:
- 基本类型传递"值的副本",修改副本不影响原值。
- 引用类型传递"引用的副本",通过副本可修改对象内容,但无法改变原引用的指向。