Java导论

理解本博客需要初步了解面向对象编程技术,对于面向对象编程的基本概念本博客不再介绍。

  • Java 是一种高级、面向对象、跨平台的编程语言,由 Sun Microsystems(现归属 Oracle)于 1995 年推出。它以 “Write Once, Run Anywhere”(一次编写,随处运行) 为目标,广泛用于桌面应用Web 开发移动应用企业级系统和物联网

  • Java 的跨平台性运行时优化机制 是其核心优势,尤其在企业级和大数据开发中占据重要地位。

Java 的主要特点

特性

  1. 跨平台性
    • Java 通过 Java 虚拟机(JVM)实现跨平台。编译后的字节码(.class 文件)可以在任意安装 JVM 的操作系统上运行。
  2. 面向对象
    • 支持类、对象、继承、多态等特性,采用封装、继承和多态作为核心设计思想。
  3. 安全性
    • Java 在编译和运行时提供多重安全机制,包括字节码验证、沙箱模型和内存管理。
  4. 多线程
    • Java 内置多线程支持,适合开发并发和高性能的程序。
  5. 动态性
    • Java 程序可以动态加载类库,适应运行时环境的变化。
  6. 高性能
    • 虽然 Java 是解释执行的语言,但现代 JVM 的即时编译(JIT)技术大幅提高了性能。

Java 的核心组件

1. Java语言

2. 依赖环境

  • Java 虚拟机(JVM)

    JVM 是 Java 程序的运行核心,它负责加载字节码文件(.class 文件),并将字节码解释或编译成机器码,在不同的操作系统上提供统一的运行环境,实现了 Java 的 “一次编写,到处运行” 特性。

  • Java 运行时环境(JRE)

    JRE 是运行 Java 程序所必需的环境,它包含了 JVM 和 Java 核心类库。如果你只需要运行 Java 程序,安装 JRE 即可。

  • Java 开发工具包(JDK)

    JDK 是 Java 开发人员使用的工具包,它包含了 JRE 和一系列开发工具,如编译器(javac)、调试器等。如果你要开发 Java 程序,需要安装 JDK。

包含关系:JDK > JRE > JVM

3. 类库

  1. Java 标准类库

Java 标准类库是 Java 提供的一系列预定义类和接口,涵盖了各种功能,如输入输出、网络编程、数据结构等。常见的包有:

  • java.lang:包含了 Java 语言的核心类,如 ObjectStringThread 等,该包会被自动导入。
  • java.util:提供了常用的工具类和集合框架,如 ArrayListHashMap 等。
  • java.io:用于实现输入输出操作,如文件读写、网络数据传输等。
  • java.net:提供了网络编程的相关类和接口,如 SocketServerSocket 等。
  1. Java 扩展类库

除了标准类库,Java 还有许多扩展类库,如 JavaFX(用于创建富客户端应用程序)、JDBC(用于数据库连接)等

Java 的运行机制

Java 的运行机制可以分为以下几个阶段:

1. 编写源代码

  • 开发者用 Java 编程语言编写 .java 文件。

  • 示例代码:

    1
    2
    3
    4
    5
    public class HelloWorld {
    public static void main(String[] args) {
    System.out.println("Hello, World!");
    }
    }

2. 编译

  • 使用 javac 编译器将 .java 文件编译为字节码(.class 文件)。
  • 字节码是一种与平台无关的中间代码,能够被 JVM 执行。

3. 加载

  • JVM 的类加载器(Class Loader)将字节码文件加载到内存。

4. 解释与执行

  • JVM 通过解释器逐行将字节码转换为机器码。
  • 为提升性能,现代 JVM 使用即时编译器(JIT,Just-In-Time Compiler)将热点代码直接编译为机器码以提高运行速度。

5. 执行结果

  • 最终由底层硬件执行生成的机器指令,并输出运行结果。

运行结构图

1
2
3
4
5
6
7
源代码(.java)
↓ 编译(javac)
字节码文件(.class)
↓ 加载(Class Loader)
Java 虚拟机(JVM)
↓ 转换(解释/即时编译)
操作系统与硬件执行

Java 的典型应用领域

  1. Web 开发:Spring、Hibernate、Struts 等框架广泛应用于后端开发。
  2. 移动开发:Android 应用开发使用 Java 作为主要语言(逐步被 Kotlin 替代)。
  3. 企业级应用:Java EE 被用于银行、保险和电信等行业的企业级开发。
  4. 大数据:Hadoop、Spark 等大数据工具依赖 Java。
  5. 物联网:Java 的平台无关性和多线程支持使其适合 IoT 开发。

字节码

字节码(Bytecode)是一种中间形式的代码,它在编程语言的编译和执行过程中扮演着重要角色,下面从不同角度为你详细介绍:

定义

字节码是一种特殊的二进制代码,它介于高级编程语言代码(如 Java、Python 的源代码)和机器码(计算机硬件能够直接执行的指令)之间。字节码通常由高级语言的源代码经过编译器编译生成,它不是直接可以在计算机硬件上运行的机器码,而是一种面向虚拟机的代码格式

以 Java 为例理解字节码

  • 生成过程:在 Java 中,程序员编写的 .java 源文件,经过 Java 编译器(javac)编译后,会生成 .class 文件,这个 .class 文件中存储的就是字节码。例如,有一个简单的 Java 程序:
1
2
3
4
5
6
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

使用 javac HelloWorld.java 命令编译该源文件,就会生成 HelloWorld.class 文件,其中包含了该程序对应的字节码。

执行过程

  • Java 字节码不能直接在操作系统上运行,而是由 Java 虚拟机(JVM)来执行。
  • JVM 会读取 .class 文件中的字节码,将其解释或编译成机器码,然后在特定的操作系统和硬件平台上运行。
  • 这种方式使得 Java 程序具有 “一次编写,到处运行” 的特性,因为只要在不同的平台上安装了对应的 JVM,就可以运行相同的 Java 字节码。

字节码的优势

  • 平台无关性:字节码可以在不同的操作系统和硬件平台上运行,只要该平台上有对应的虚拟机支持。例如,Java 字节码可以在 Windows、Linux、Mac OS 等多种操作系统上运行,而不需要针对每个平台重新编写和编译代码。
  • 安全性:字节码在执行之前可以经过虚拟机的安全检查,确保代码不会对系统造成危害。例如,Java 虚拟机在加载字节码时会进行类文件格式检查、访问权限检查等,防止恶意代码的执行。
  • 优化潜力:虚拟机可以对字节码进行优化,提高代码的执行效率。例如,JVM 中的即时编译器(JIT)可以在运行时将频繁执行的字节码编译成高效的机器码,从而提升程序的性能。

其他使用字节码的语言

除了 Java 之外,还有很多编程语言也使用字节码技术,例如:

  • Python:Python 源代码会被编译成字节码(.pyc 文件),然后由 Python 解释器(如 CPython)来执行这些字节码。
  • C#:C# 代码经过编译后会生成中间语言(IL)字节码,这些字节码在 .NET 平台的公共语言运行时(CLR)中执行。

第一个java程序

1
2
3
4
5
6
7
8
public class HelloWorld {
/* 第一个Java程序
* 它将输出字符串 Hello World
*/
public static void main(String[] args) {
System.out.println("Hello World"); // 输出 Hello World
}
}

下面将逐步介绍如何保存、编译以及运行这个程序:

  • 打开代码编辑器,把上面的代码添加进去;
  • 把文件名保存为:HelloWorld.java;(源文件名必须和类名相同)
  • 打开 cmd 命令窗口,进入目标文件所在的位置,假设是 C:\
  • 在命令行窗口输入 javac HelloWorld.java 按下回车键编译代码。如果代码没有错误,cmd 命令提示符会进入下一行(假设环境变量都设置好了)。
  • 再键输入 java HelloWorld 按下回车键就可以运行程序了

如果遇到编码问题,我们可以使用 -encoding 选项设置 utf-8 来编译:

1
2
javac -encoding UTF-8 HelloWorld.java 
java HelloWorld

基本语法

示例语句

1
public static void main (String [] args)
  • 公共的、静态的、无返回值的主方法,该方法接受一个字符串类型的数组作为参数

img

这是 Java 语言中程序执行的入口方法,当你运行一个 Java 程序时,JVM(Java 虚拟机)会从这个方法开始执行。其中:

  • public :修饰符,表示该方法是公共的,可以被任何类访问
  • static :修饰符,表示该方法是静态的不需要创建类的实例就可以调用。
  • void: 表示该方法没有返回值。
  • main 标识符,是方法名,这是一个固定的名称,JVM 会识别这个方法作为程序的入口。所有的方法名都应该以小写字母开头
  • String[] args 是方法的参数,是一个字符串类型的数组用于接收命令行参数

一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。

编写规则

编写 Java 程序时,应注意以下几点:

  • 大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
  • 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass
  • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
  • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
  • 主方法入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行。

-

Java注释

类似于 C/C++、Java 也支持单行以及多行注释。

注释中的字符将被 Java 编译器忽略。

1
2
3
4
5
6
7
8
9
10
11
public class HelloWorld {
/* 这是第一个Java程序
* 它将输出 Hello World
* 这是一个多行注释的示例
*/
public static void main(String[] args){
// 这是单行注释的示例
/* 这个也是单行注释的示例 */
System.out.println("Hello World");
}
}

Java 源程序与编译型运行区别

如下图所示:

Java 关键字

下面列出了 Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。

关键字 说明
abstract 用于声明抽象类或抽象方法
assert 用于断言某个条件为真,通常用于调试。
boolean 用于声明布尔类型的变量(truefalse)。
break 用于跳出循环或switch语句。
byte 用于声明字节类型的变量(8位整数)。
case 用于switch语句中的分支。
catch 用于捕获异常。
char 用于声明字符类型的变量(16位Unicode字符)。
class 用于声明类。
const 保留关键字,未使用。
continue 用于跳过当前循环的剩余部分,继续下一次循环。
default 用于switch语句中的默认分支。
do 用于声明do-while循环。
double 用于声明双精度浮点数类型的变量(64位浮点数)。
else 用于if语句的否定分支。
enum 用于声明枚举类型
extends 用于声明一个类继承另一个类
final 用于声明常量、不可继承的类或不可重写的方法。
finally 用于try-catch块中,无论是否发生异常都会执行的代码块。
float 用于声明单精度浮点数类型的变量(32位浮点数)。
for 用于声明for循环。
goto 保留关键字,未使用。
if 用于声明条件语句。
implements 用于声明类实现一个或多个接口
import 用于导入包或类
instanceof 用于检查对象是否是某个类的实例
int 用于声明整数类型的变量(32位整数)。
interface 用于声明接口。
long 用于声明长整数类型的变量(64位整数)。
native 用于声明本地方法(由非Java代码实现的方法)。
new 用于创建新对象。
package 用于声明包。
private 用于声明私有成员(仅在类内部可见)。
protected 用于声明受保护的成员(在类内部、子类和同一包内可见)。
public 用于声明公共成员(在任何地方可见)。
return 用于从方法中返回值。
short 用于声明短整数类型的变量(16位整数)。
static 用于声明静态成员(属于类而不是实例)。
strictfp 用于声明严格浮点计算(确保浮点运算在不同平台上结果一致)。
super 用于引用父类的成员调用父类的构造方法
switch 用于声明多分支选择语句。
synchronized 用于声明同步方法或代码块(线程安全)。
this 用于引用当前对象的实例
throw 用于抛出异常。
throws 用于声明方法可能抛出的异常。
transient 用于声明不需要序列化的字段。
try 用于声明可能抛出异常的代码块。
void 用于声明无返回值的方法。
volatile 用于声明易变变量(确保多线程环境下的可见性)。
while 用于声明while循环。

注意:

  • constgoto 是Java的保留关键字,但目前并未使用。
  • truefalsenull 是字面量,不是关键字,但也不能用作标识符。