Skip to content

Java 快速指南

Java 是一种高级的、基于类的、面向对象的编程语言,设计目标是尽可能减少实现依赖。主要特性包括:

  • Object-Oriented(面向对象):将软件设计围绕数据或对象组织,而不是函数和逻辑。例如:一个特定的 Dog 对象可能具有 color=“Brown”、name=“Buddy”、breed=“Labrador” 等状态,以及 bark()、wagTail()、eat() 等行为。
  • Platform Independent(平台无关):借助 Java Virtual Machine (JVM) 实现“一次编写,随处运行”(Write Once, Run Anywhere - WORA)。
  • Simple(简单):设计得相对容易学习,尤其是与 C++ 相比。
  • Secure(安全):Security Manager 等特性允许安全地执行不受信任的代码。
  • Architecture-Neutral(架构无关):编译后的代码(字节码 - bytecode)可以在任何具有兼容 JVM 的处理器上运行。
  • Portable(可移植):相同的代码无需修改即可在不同平台上运行。
  • Robust(健壮):强大的内存管理和异常处理机制减少了常见的编程错误。
  • Multi-threaded(多线程):支持程序多个部分的并发执行。
  • Interpreted & High Performance(解释型与高性能):字节码由 JVM 解释执行,JVM 使用即时编译(Just-In-Time - JIT)以提高性能。
  • Distributed(分布式):便于开发分布式应用程序。
  • Dynamic(动态):设计用于适应不断发展的环境。

要开发 Java 应用程序,您需要 Java Development Kit (JDK)。您可以从各种提供商下载 JDK。常见的选择包括 Oracle JDK 和 OpenJDK 的分发版本,如 Eclipse Temurin、Amazon Corretto 或 Azul Zulu。建议使用长期支持(Long-Term Support - LTS)版本(例如 Java 11、17、21)以获得稳定性。

各个 JDK 提供商的网站上提供了安装指南。现代开发通常包括:

  • 安装 JDK 并设置 JAVA_HOME 环境变量。
  • 使用集成开发环境(Integrated Development Environment - IDE),如 IntelliJ IDEA、Eclipse 或带有 Java 扩展的 Visual Studio Code,进行编码、调试和运行应用程序。
  • 使用构建自动化工具(build automation tool),如 Maven 或 Gradle,来管理项目依赖、编译、测试和打包。

有关详细的设置说明,请参考您选择的 JDK、IDE 和构建工具的文档。

  • Object(对象):类的一个实例,拥有状态(数据)和行为(方法)。例如:一个特定的 Dog 对象可能具有 color=“Brown”、name=“Buddy”、breed=“Labrador” 等状态,以及 bark()、wagTail()、eat() 等行为。
  • Class(类):用于创建对象的蓝图或模板。它定义了所有该类型对象将拥有的属性(字段/变量)和动作(方法)。
  • Method(方法):类中执行特定任务的代码块。方法定义了对象的行为,并包含操作数据的逻辑。
  • Instance Variables(实例变量):在类中声明但在任何方法之外的变量。类的每个对象(实例)都有自己的这些变量副本,定义了其独特的状态。

让我们看一个简单的程序,它将“Hello, Modern World!”打印到控制台:

public class MyFirstJavaProgram {
/*
* 这是一个经典的Java入门程序。
* 它展示了基本结构,并向控制台打印一条消息。
*/
// main方法是所有Java应用程序的入口点。
public static void main(String[] args) {
// System.out.println 用于向标准输出流(通常是控制台)打印输出。
System.out.println("Hello, Modern World!");
}
}

关于 Java 程序需要记住的要点:

  • Case Sensitivity(区分大小写):Java 区分大小写。myVariable 和 myvariable 被视为不同的标识符。
  • Class Names(类名):按照约定,类名以大写字母开头并使用 UpperCamelCase(例如,MyFirstJavaProgram)。
  • Method Names(方法名):按照约定,方法名以小写字母开头并使用 lowerCamelCase(例如,myMethodName())。
  • File Name(文件名):源文件名称必须与文件中 public 类的名称完全匹配,并加上 .java 后缀(例如,MyFirstJavaProgram.java)。
  • Main Method(主方法):程序执行始于 public static void main(String[] args) 方法。此签名是必需的。String… args (可变参数 - varargs) 也有效。

标识符(Identifiers)是赋予类、方法、变量、包等的名称。标识符的规则:

  • 必须以字母(a-z, A-Z)、货币符号($)或下划线(_)开头。
  • 后续字符可以是字母、数字(0-9)、货币符号或下划线。
  • 不能是 Java 关键字(保留字,如 class, int, public)。
  • 区分大小写。
  • 有效标识符示例:age, $salary, _value, __1_value, userName。
  • 无效标识符示例:123abc(以数字开头),-salary(以连字符开头),class(关键字)。

修饰符(Modifiers)改变类、方法、变量等的含义或可访问性。它们分为两大类:

  • Access Modifiers(访问修饰符):控制可见性。public(随处可访问),protected(在包内和子类中可访问),default(包私有,仅在同一包内可访问),private(仅在声明类内部可访问)。
  • Non-Access Modifiers(非访问修饰符):提供其他特性。主要例子包括 static(属于类,不属于实例),final(不能改变/子类化/重写),abstract(必须由子类实现),synchronized(控制线程访问),volatile(确保更改在线程间的可见性),transient(不参与序列化)。strictfp 确保平台无关的浮点结果(现在较少使用)。

理解修饰符对于正确的面向对象设计和并发控制至关重要。

变量是用于存储数据值的容器。Java 根据作用域(scope)有三种主要类型:

  • Local Variables(局部变量):在方法、构造方法或块内部声明。它们的作用域仅限于该块。
  • Instance Variables(实例变量,非静态字段):在类内部声明但在任何方法之外。每个对象实例都有自己的副本。
  • Class Variables(类变量,静态字段):在类内部使用 static 关键字声明,在任何方法之外。所有类的实例共享同一个副本。

从 Java 10 开始,您可以使用 var 进行局部变量的类型推断(type inference),编译器会从初始化器中推断出类型:var message = “Hello”;

数组(Arrays)是固定大小的、索引集合,存储多个相同数据类型的元素。它们是位于堆(heap)上的对象。

声明和初始化示例:

// Declare an array of integers
int[] numbers;
// Allocate memory for 5 integers
numbers = new int[5];
// Initialize elements
numbers[0] = 10;
numbers[1] = 20;
// ... and so on
// Shorthand declaration and initialization
String[] names = {"Alice", "Bob", "Charlie"};

虽然数组是基础,但对于动态集合(大小可以改变),Java Collections Framework(例如,ArrayList、LinkedList、HashMap)通常更灵活且更受欢迎。

枚举(Enums)定义了一种具有一组固定命名常量的类型。与使用普通常量(例如,整数或字符串)相比,它们提高了类型安全和代码清晰度。

示例:表示固定大小。

enum Size {
SMALL, MEDIUM, LARGE
}
public class CoffeeOrder {
private Size cupSize;
public void setSize(Size size) {
this.cupSize = size;
}
public Size getSize() {
return cupSize;
}
public static void main(String[] args) {
CoffeeOrder order = new CoffeeOrder();
order.setSize(Size.MEDIUM);
System.out.println("Ordered cup size: " + order.getSize()); // Output: Ordered cup size: MEDIUM
}
}

Java 中的枚举功能强大:它们可以有字段、方法和构造方法,并且可以实现接口。它们本质上是特殊类型的类。

关键字(Keywords)是 Java 语言中具有预定义含义的保留字。它们不能用作标识符。以下是一些常用关键字列表(注意:const 和 goto 是保留字但未使用):

abstractassertbooleanbreak
bytecasecatchchar
classcontinuedefault
dodoubleelseenum
extendsfinalfinallyfloat
forifimplements
importinstanceofintinterface
longnativenewpackage
privateprotectedpublicreturn
shortstaticstrictfpsuper
switchsynchronizedthisthrow
throwstransienttryvoid
volatilewhilevarrecord
sealedpermitsnon-sealedyield

注释(Comments)会被编译器忽略,用于解释代码。Java 支持三种类型:

public class CommentDemo {
// 这是单行注释。它以行尾结束。
/*
* 这是多行注释。
* 它可以跨越多行。
*/
/**
* 这是 Javadoc 注释。它用于生成 API 文档。
* 通常用于类、方法或字段声明之前。
* @param args 命令行参数(此处未使用)。
*/
public static void main(String[] args) {
System.out.println("Demonstrating comments."); // 代码后的注释
}
}

Java 有两类数据类型:

  • Primitive Data Types(基本数据类型):语言内置的基本类型。它们直接存储简单值。
  • Reference/Object Data Types(引用/对象数据类型):引用对象(类的实例)。它们存储对象数据所在的内存地址。

Java 支持八种基本数据类型:

  • byte:8位整数。
  • short:16位整数。
  • int:32位整数(最常用作整数)。
  • long:64位整数(当 int 不够大时使用)。后缀 L 或 l(例如,100L)。
  • float:32位单精度浮点数。后缀 F 或 f(例如,3.14f)。
  • double:64位双精度浮点数(十进制数的默认类型)。后缀 D 或 d 可选。
  • boolean:表示 true 或 false 值。
  • char:16位 Unicode 字符(用单引号括起来,例如,‘A’)。
  • 引用变量使用类构造方法(例如,String name = new String(“Java”); 或者对于 String 直接使用 String name = “Java”;)创建。
  • 它们持有对对象的引用(内存地址)。
  • 例子包括 String、数组、自定义类的实例(Dog, CoffeeOrder)、接口和枚举。
  • 任何引用变量的默认值都是 null,表示它不引用任何对象。
  • 引用变量可以引用其声明类型或任何兼容子类型(多态性 - polymorphism)的对象。

字面量(Literal)是源代码中直接表示的固定值。

各种字面量示例:

int count = 100; // Integer literal
long bigNumber = 9876543210L; // Long literal (note the L)
double price = 29.99; // Double literal
float pi = 3.14f; // Float literal (note the f)
boolean isValid = true; // Boolean literal
char grade = 'A'; // Character literal
String message = "Hello"; // String literal
// Text Block (Java 15+) for multi-line strings
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>""";

String 和 char 字面量支持特殊的转义序列(escape sequences)来表示字符,如换行(\n)、制表符(\t)、反斜杠(\)、单引号(‘)和双引号(”)。

NotationCharacter Represented
\nNewline(换行符)
\rCarriage return(回车符)
\fFormfeed(换页符)
\bBackspace(退格符)
\tTab(制表符)
“Double quote(双引号)
‘Single quote(单引号)
\Backslash(反斜杠)

访问修饰符(Access modifiers)控制类、构造方法、字段和方法的访问性:

  • public:可从任何其他类访问。
  • protected:可在其自己的包内以及子类中访问(即使在不同包中)。
  • default(无关键字):包私有。只能由同一包内的类访问。
  • private:只能在声明类本身内部访问。

选择正确的访问级别是封装(encapsulation)的关键,封装是面向对象编程(OOP)的核心原则。

运算符(Operators)对变量和值执行操作。常见类别包括:

执行数学计算。示例:int a = 10, b = 3;

OperatorDescriptionExampleResult
+Addition(加法)a + b13
-Subtraction(减法)a - b7
*Multiplication(乘法)a * b30
/Division(除法,int 类型为整数除法)a / b3
%Modulus(取余)a % b1
++Increment(递增,前缀/后缀)a++ (value is 10, then a becomes 11)Varies
—Decrement(递减,前缀/后缀)—b (value is 2, b becomes 2)Varies

比较两个值,结果为 boolean(true 或 false)。示例:int x = 5, y = 8;

OperatorDescriptionExampleResult
==Equal to(等于)x == yfalse
!=Not equal to(不等于)x != ytrue
>Greater than(大于)x > yfalse
<Less than(小于)x < ytrue
>=Greater than or equal to(大于或等于)x >= 5true
<=Less than or equal to(小于或等于)y <= 8true

对整数类型的单个位进行操作。在通用应用程序代码中不常用,但在特定场景中使用(例如,低级编程、标志位操作)。示例:int a = 5; // 0101, int b = 3; // 0011

OperatorDescriptionExampleResult (Binary)
&Bitwise AND(按位与)a & b1 (0001)
|Bitwise OR(按位或)a | b7 (0111)
^Bitwise XOR(按位异或)a ^ b6 (0110)
~Bitwise Complement(按位补)~a-6 (Inverts all bits)
<<Left Shift(左移)a << 110 (1010)
>>Signed Right Shift(有符号右移)a >> 12 (0010)
>>>Unsigned Right Shift(无符号右移)a >>> 12 (0010, same for positive numbers)

组合布尔表达式。示例:boolean p = true, q = false;

OperatorDescriptionExampleResult
&&Logical AND(逻辑与,短路)p && qfalse
||Logical OR(逻辑或,短路)p || qtrue
!Logical NOT(逻辑非)!pfalse

为变量赋值。复合运算符一步完成操作和赋值。

OperatorDescriptionExample
=Simple Assignment(简单赋值)int c = 10;
+=Add and Assign(加后赋值)c += 5; (c = c + 5)
-=Subtract and Assign(减后赋值)c -= 3; (c = c - 3)
*=Multiply and Assign(乘后赋值)c *= 2; (c = c * 2)
/=Divide and Assign(除后赋值)c /= 4; (c = c / 4)
%=Modulus and Assign(取余后赋值)c %= 3; (c = c % 3)

if-else 语句的简写形式。语法:condition ? value_if_true : value_if_false。

int score = 75;
String result = (score >= 60) ? "Pass" : "Fail"; // result will be "Pass"

检查对象是否是特定类、子类或接口实现的实例。返回 true 或 false。

String name = "Java";
boolean isString = name instanceof String; // isString will be true
// Modern Java (16+) includes Pattern Matching for instanceof:
Object obj = "Hello";
if (obj instanceof String s) {
// 如果 obj 是 String 类型,则将其赋值给 s
System.out.println("String length: " + s.length());
} else {
System.out.println("Not a String");
}

决定表达式中运算符的计算顺序。括号 () 可以覆盖优先级。优先级高的运算符先计算。请查阅 Java 文档获取完整的优先级表。

高级优先级示例(从高到低):后缀 (expr++, expr--)、一元 (++expr, !, ~)、乘法 (*, /, %)、加法 (+, -)、移位 (<<, >>, >>>)、关系 (<, >, <=, >=)、相等 (==, !=)、按位与 (&)、按位异或 (^)、按位或 (|)、逻辑与 (&&)、逻辑或 (||)、三元 (? :)、赋值 (=, +=, etc.)。

循环(Loops)重复执行代码块。

只要布尔条件为 true,就重复执行代码块。条件在每次迭代之前检查。

语法:

while (condition) {
// Statements to execute
}

类似于 while,但条件在块执行之后检查。保证代码块至少运行一次。

语法:

do {
// Statements to execute
} while (condition);

当已知迭代次数时,它是理想的选择。包含初始化、条件和更新表达式。

语法:

for (initialization; condition; update) {
// Statements to execute
}

示例:打印 0 到 4 的数字

for (int i = 0; i < 5; i++) {
System.out.println(i);
}

为遍历数组或集合中的元素提供了更简洁的语法。

语法:

for (ElementType variable : arrayOrCollection) {
// Statements using variable
}

示例:从数组中打印名称

String[] names = {"Alice", "Bob", "Charlie"};
for (String name : names) {
System.out.println(name);
}

修改循环内的执行流程。

立即终止它所在的最近的循环(for, while, do-while)或 switch 语句。执行继续在终止的循环/switch 后面的语句。

跳过当前迭代的最内层循环,并继续下一次迭代。在 for 循环中,它跳到更新表达式;在 while 或 do-while 中,它跳到条件检查。

语法(在循环内部使用):

break;
continue;

根据条件执行不同的代码块。

只有当布尔条件为 true 时才执行代码块。

语法:

if (condition) {
// Statements execute if condition is true
}

如果条件为 true 则执行一个块,如果为 false 则执行另一个块。

语法:

if (condition) {
// Executes when condition is true
} else {
// Executes when condition is false
}

按顺序测试多个条件。执行对应于第一个 true 条件的块。如果之前的所有条件都为 false,则执行最终的 else(可选)。

语法:

if (condition1) {
// Executes if condition1 is true
} else if (condition2) {
// Executes if condition1 is false and condition2 is true
} else if (condition3) {
// Executes if conditions 1 & 2 are false and condition3 is true
} else {
// Executes if none of the above conditions are true
}

您可以将 if-else 结构放在其他 if 或 else 块内部,以处理更复杂的条件。使用适当的缩进保持可读性。

允许测试变量与值列表(case)的相等性。对于特定值比较,比长串的 if-else if 更高效。

传统 switch(Java 14 之前):

switch (expression) {
case value1:
// Statements
break; // 重要:退出 switch
case value2:
// Statements
break;
// ... other cases
default: // 可选:如果没有 case 匹配则执行
// Statements
}

现代 switch(表达式,Java 14+):使用 ->(箭头)标签提供了更简洁且不易出错的语法,并且可以作为产生值的表达式使用。

// switch表达式示例
int day = 3;
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday"; // 箭头标签隐含了 break
case 4 -> "Thursday";
case 5 -> "Friday";
default -> "Weekend or Invalid day";
}; // 表达式需要分号
System.out.println(dayName); // Output: Wednesday
// 带有多个 case 标签和 yield 的示例
int num = 2;
String result = switch (num) {
case 1, 3, 5 -> {
System.out.println("Odd number");
yield "Odd"; // yield 用于从块中返回值
}
case 2, 4 -> {
System.out.println("Even number");
yield "Even";
}
default -> "Unknown";
};

switch 适用于 byte、short、char、int 及其包装类型(wrapper types)、enum 类型以及 String(从 Java 7 开始)。

方法(Method)是执行特定任务的代码块。它提高了代码的可重用性和组织性。

方法签名语法:

accessModifier nonAccessModifiers(opt) returnType methodName(parameterList) throws ExceptionList(opt) {
// 方法体:执行任务的代码
// 可选:如果 returnType 不是 void,则有 return 语句
}

方法的组成部分:

  • Access Modifier(访问修饰符):(例如,public, private)控制可见性。
  • Non-Access Modifiers(非访问修饰符):(例如,static, final)提供其他特性。
  • Return Type(返回类型):方法返回的值的数据类型(如果什么也不返回则为 void)。
  • Method Name(方法名):方法的标识符(遵循 lowerCamelCase 约定)。
  • Parameter List(参数列表):逗号分隔的输入变量列表(类型和名称),方法接受这些变量。可以为空 ()。Java 使用按值传递(pass-by-value)语义(传递基本类型值的副本或引用)。
  • Method Body(方法体):包含在 {} 中的代码语句。
  • Throws Clause(可选):列出方法可能抛出的已检查异常(checked exceptions)。

示例方法:

/**
* 计算两个整数的和。
* @param num1 第一个整数。
* @param num2 第二个整数。
* @return num1 和 num2 的和。
*/
public int addNumbers(int num1, int num2) {
int sum = num1 + num2;
return sum;
}

Java 本质上是面向对象的。理解类和对象至关重要。

  • Class(类):定义属性(字段/实例变量)和行为(方法)的蓝图。
  • Object(对象):类的实例,使用 new 关键字创建。每个对象都有其自己的状态,基于其实例变量的值。

示例 Car 类:

public class Car {
// 实例变量(状态)
String make;
String model;
int year;
// 构造方法(创建对象的特殊方法)
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}
// 方法(行为)
public void displayInfo() {
System.out.println("Car: " + year + " " + make + " " + model);
}
public static void main(String[] args) {
// 创建 Car 对象(实例)
Car myCar1 = new Car("Toyota", "Camry", 2023);
Car myCar2 = new Car("Honda", "Civic", 2022);
// 调用对象的方法
myCar1.displayInfo(); // Output: Car: 2023 Toyota Camry
myCar2.displayInfo(); // Output: Car: 2022 Honda Civic
}
}

类上下文中的变量类型:

  • Local Variables(局部变量):在方法/构造方法/块内部。
  • Instance Variables(实例变量):在类中声明,方法外部。每个对象都有自己的副本。
  • Class Variables(类变量,static):使用 static 声明。在类的所有对象之间共享。

异常(Exceptions)是中断程序正常执行流程的事件(例如,文件未找到、输入无效)。Java 提供了机制来优雅地处理它们。

可能抛出异常的代码放在 try 块中。紧随其后的是 catch 块,用于在异常发生时处理特定类型的异常。

try {
// 可能抛出异常的代码(例如,除以零)
int result = 10 / 0;
} catch (ArithmeticException e) {
// 处理 ArithmeticException 的代码
System.err.println("Error: Division by zero! " + e.getMessage());
}

您可以有多个 catch 块来处理不同的异常类型。从 Java 7 开始,您可以使用单个 catch 块通过 | 运算符处理多种异常类型(多重捕获 - multi-catch)。

try {
// Code that might throw different exceptions
} catch (IOException | SQLException e) {
// 处理 IOException 或 SQLException
System.err.println("I/O or SQL Error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
// 处理数组索引错误
System.err.println("Array index out of bounds: " + e.getMessage());
} catch (Exception e) {
// 捕获任何其他一般性异常(通常放在最后)
System.err.println("An unexpected error occurred: " + e.getMessage());
}
  • Checked Exceptions(已检查异常):编译器强制您处理的异常(要么使用 try-catch,要么使用 throws 声明)。它们通常表示程序外部可恢复的条件(例如,IOException, SQLException)。
  • Unchecked Exceptions (Runtime Exceptions)(未检查异常,运行时异常):通常是编程错误导致的异常(例如,NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException)。编译器不要求显式处理,但它们仍然可以被捕获。

如果一个方法可能抛出已检查异常但未使用 try-catch 处理它,它必须在其签名中使用 throws 关键字声明该异常。这会将处理异常的责任传递给调用者(caller)。

public void readFile(String fileName) throws IOException {
// 可能抛出 IOException 的代码
}

用于显式抛出一个异常对象(通常是新创建的)。可用于指示错误条件。

if (input < 0) {
throw new IllegalArgumentException("Input cannot be negative.");
}

finally 块紧随 try 和任何 catch 块之后,总是执行,无论是否发生或捕获到异常。它通常用于清理操作(例如,关闭文件或网络连接)。

try {
// 有风险的代码
} catch (Exception e) {
// 处理异常
} finally {
// 总是运行的清理代码
System.out.println("Executing finally block.");
}

Java 7 中引入,这是处理需要关闭的资源(如文件流或数据库连接)的首选方式。它会自动关闭在其括号内声明的资源,即使发生异常,从而使资源关闭的 finally 块通常变得不必要,并减少样板代码(boilerplate code)。

// 示例:从文件中读取
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
// 即使发生异常,'reader' 也会在此处自动关闭。

本快速指南涵盖了基础知识。要更深入地理解 Java,请探索 Collections Framework、Generics、Concurrency、I/O Streams、Lambdas、Streams API 和 modules 等主题。