一、.基础知识
Java 简介:Java 的历史、特点、版本发展。
1. 什么是Java?
Java 是一种广泛使用的面向对象编程语言,由 Sun Microsystems 公司在 1995 年 5 月推出,主要由 James Gosling 和他的同事们共同研发。2010 年,随着 Sun Microsystems 被 Oracle 公司收购,Java 也成为了 Oracle 公司的产品。Java 的设计理念是“一次编写,到处运行”(Write Once, Run Anywhere, WORA),这意味着编写的 Java 程序可以在任何支持 Java 的平台上运行,而无需重新编译。
2. Java 的特点
简单性:Java 的语法与 C++ 类似,但去除了 C++ 中的一些复杂和容易出错的特性,如指针和多继承,使得 Java 更加简单易学。
面向对象:Java 是一种纯面向对象的语言,支持封装、继承和多态等面向对象的概念。
分布式:Java 设计之初就考虑到了网络应用的需求,提供了丰富的网络编程接口,如 Socket、URL 和 RMI(远程方法调用)。
解释型:Java 程序首先被编译成字节码(.class 文件),然后在 Java 虚拟机(JVM)上解释执行。
健壮性:Java 通过严格的类型检查、异常处理机制和垃圾回收机制,确保程序的健壮性和稳定性。
安全性:Java 提供了多层次的安全机制,如类加载器、字节码验证和安全管理器,确保程序的安全性。
平台无关性:Java 通过 JVM 实现了“一次编写,到处运行”的理念,使得 Java 程序可以在不同的平台上运行。
可移植性:Java 严格规定了各个基本数据类型的长度,确保了程序的可移植性。
高性能:尽管 Java 是解释型语言,但通过 JIT(Just-In-Time)编译器技术,Java 的性能已经接近于 C++。
多线程:Java 内置了多线程支持,使得开发并发程序更加容易。
动态性:Java 支持动态加载类,可以适应不断变化的环境。
1991年:Sun 公司成立了一个名为“Green”的项目组,目标是开发一种用于消费性电子产品的编程语言,最初命名为 Oak。
3、Java的发展历程
1992年:Oak 语言开发成功,但由于市场需求不足,项目被搁置。
1994年:随着互联网的兴起,Sun 公司决定将 Oak 语言应用于互联网编程,开发了可以嵌入网页的小程序(Applet)。
1995年5月23日:Sun 公司在 SunWorld 会议上正式发布了 Java 和 HotJava 浏览器,将 Oak 语言更名为 Java。
1996年1月:Sun 公司发布了 Java 的第一个开发工具包(JDK 1.0)。
1997年2月:JDK 1.1 发布,引入了内省(Introspection)和反射(Reflection)机制。
1998年12月8日:发布了 J2EE(Java 2 Platform, Enterprise Edition),为企业级应用提供了支持。
1999年6月:Sun 公司发布了 J2SE(Java 2 Platform, Standard Edition)、J2EE 和 J2ME(Java 2 Platform, Micro Edition),分别针对桌面、企业和嵌入式应用。
2005年6月:JavaOne 大会上,Sun 公司发布了 Java SE 6,取消了版本号中的“2”。
2006年11月13日:Sun 公司宣布将 Java 技术作为免费软件对外发布。
2009年:Oracle 公司宣布收购 Sun Microsystems,Java 成为 Oracle 的产品。
2010年:Java 编程语言的共同创始人之一詹姆斯·高斯林从 Oracle 公司辞职。
2011年:Oracle 公司发布了 Java 7,引入了多个新特性。
2014年:Oracle 公司发布了 Java 8,引入了 Lambda 表达式和 Stream API。
2017年9月22日:Java 9 正式发布,引入了模块化系统(Jigsaw 项目)。
2024年3月20日:Oracle 正式发布 Java 22,带来了数千种改进,包括对 Java 语言、API 和性能的增强。
4、Java可以用来干什么
Web 应用开发:Java 是开发企业级 Web 应用程序的主流语言,常用的框架有 Spring、Hibernate、Struts 等。
移动应用开发:Android 操作系统基于 Java,几乎所有的 Android 应用程序都是用 Java 或 Kotlin(兼容 Java 虚拟机)编写的。
金融服务:Java 在金融服务业广泛应用,许多投资银行和金融机构使用 Java 开发交易系统和数据分析工具。
大数据技术:Hadoop、Elasticsearch 等大数据技术大量使用 Java。
嵌入式系统:Java 在嵌入式设备中也有应用,如智能手表、智能家居设备等。
桌面应用:Java 提供了 AWT、Swing 和 JavaFX 等 GUI 库,用于开发桌面应用程序。
科学计算:Java 由于其强大的功能和安全性,常用于科学计算和数据分析。
游戏开发:虽然 Java 不是游戏开发的首选语言,但一些轻量级游戏和模拟器使用 Java 开发。
开发工具:Eclipse、IntelliJ IDEA、NetBeans 等 IDE(集成开发环境)提供了丰富的功能,帮助开发者高效开发 Java 应用。
构建工具:Maven、Gradle 等构建工具帮助管理项目依赖和构建过程。
测试框架:JUnit、TestNG 等测试框架帮助开发者编写和运行单元测试。
Web 框架:Spring、Spring Boot、Struts、Hibernate 等框架简化了 Web 应用的开发。
持久层框架:Hibernate、MyBatis 等框架帮助开发者管理数据库操作。
二、语法基础
数据类型:基本数据类型、引用数据类型。
基本数据类型是 Java 中最基础的数据类型,它们直接存储值,而不是引用。Java 提供了八种基本数据类型:
整数类型
byte
:8 位有符号整数,范围从 -128 到 127。short
:16 位有符号整数,范围从 -32,768 到 32,767。int
:32 位有符号整数,范围从 -2,147,483,648 到 2,147,483,647。long
:64 位有符号整数,范围从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。浮点类型
float
:32 位浮点数,精度约为 6-7 位小数。double
:64 位浮点数,精度约为 15 位小数。字符类型
char
:16 位 Unicode 字符,范围从\u0000
到\uFFFF
。布尔类型
boolean
:表示真或假,只有两个值:true
和false。
引用数据类型存储的是对象的引用(即内存地址),而不是实际的数据。引用数据类型主要包括以下几种:
1、类(Class)
- 用户自定义的类,例如:
class Person {String name;int age; }
接口(Interface)
- 用户自定义的接口,例如:
interface Animal {void eat(); }
数组(Array)
- 用于存储多个相同类型的元素,例如:
int[] numbers = new int[5]; String[] names = {"Alice", "Bob", "Charlie"};
枚举(Enum)
- 用于定义一组固定的常量,例如:
enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
字符串(String)
- 用于表示文本,实际上是不可变的字符序列,例如:
String message = "Hello, World!";
示例代码
下面是一些示例代码,展示了如何使用基本数据类型和引用数据类型:
public class DataTypesExample {public static void main(String[] args) {// 基本数据类型byte b = 10;short s = 100;int i = 1000;long l = 10000L;float f = 23.4f;double d = 12.345;char c = 'A';boolean bool = true;// 输出基本数据类型System.out.println("byte: " + b);System.out.println("short: " + s);System.out.println("int: " + i);System.out.println("long: " + l);System.out.println("float: " + f);System.out.println("double: " + d);System.out.println("char: " + c);System.out.println("boolean: " + bool);// 引用数据类型String str = "Hello, Java!";Person person = new Person();person.name = "Alice";person.age = 30;int[] numbers = {1, 2, 3, 4, 5};Day day = Day.MONDAY;// 输出引用数据类型System.out.println("String: " + str);System.out.println("Person: " + person.name + ", " + person.age);System.out.println("Array: " + java.util.Arrays.toString(numbers));System.out.println("Enum: " + day);} }class Person {String name;int age; }enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
- 基本数据类型:直接存储值,占用固定大小的内存空间。
- 引用数据类型:存储的是对象的引用(内存地址),实际数据存储在堆内存中。
理解这两种数据类型的区别和使用场景对于编写高效、正确的 Java 程序非常重要。希望这些内容对你有所帮助!如果有任何疑问,欢迎继续提问。。
变量:声明、初始化、作用域。
1. 变量的声明
变量的声明是指指定变量的名称和数据类型。语法如下:
dataType variableName;
例如:
int age; double salary; char grade; boolean isStudent;
2. 变量的初始化
变量的初始化是指给变量赋一个初始值。可以在声明变量的同时进行初始化,也可以在声明之后再初始化。
在声明时初始化
int age = 25; double salary = 5000.0; char grade = 'A'; boolean isStudent = true;
在声明后初始化
int age; age = 25;double salary; salary = 5000.0;char grade; grade = 'A';boolean isStudent; isStudent = true;
3. 变量的作用域
变量的作用域决定了变量在代码中的可见性和生命周期。Java 中主要有以下几种作用域:
局部变量(Local Variables)
局部变量是在方法、构造方法或块中声明的变量。它们的作用域仅限于声明它们的方法、构造方法或块内。
public class LocalVariableExample {public void printNumbers() {int number = 10; // 局部变量System.out.println(number);} }
实例变量(Instance Variables)
实例变量是在类中声明但在方法、构造方法或块之外声明的变量。每个对象都有自己的一份实例变量副本。
public class InstanceVariableExample {int number; // 实例变量public void setNumber(int num) {number = num;}public int getNumber() {return number;} }
静态变量(Static Variables)
静态变量是在类中使用
static
关键字声明的变量。它们属于类本身,而不是类的实例。所有对象共享同一个静态变量。public class StaticVariableExample {static int count = 0; // 静态变量public StaticVariableExample() {count++;}public static int getCount() {return count;} }
参数变量(Parameter Variables)
参数变量是在方法声明中作为参数传递的变量。它们的作用域仅限于方法内部。
public class ParameterVariableExample {public void printSum(int a, int b) {int sum = a + b; // 参数变量 a 和 bSystem.out.println(sum);} }
4、示例代码
下面是一个综合示例,展示了不同类型的变量及其作用域:
public class VariableScopeExample {int instanceVar = 10; // 实例变量public static void main(String[] args) {StaticVariableExample obj1 = new StaticVariableExample();StaticVariableExample obj2 = new StaticVariableExample();System.out.println("Count: " + StaticVariableExample.getCount()); // 输出 2VariableScopeExample example = new VariableScopeExample();example.printNumbers();example.printSum(5, 15);}public void printNumbers() {int localVar = 20; // 局部变量System.out.println("Local variable: " + localVar);System.out.println("Instance variable: " + instanceVar);}public void printSum(int a, int b) {int sum = a + b; // 参数变量 a 和 bSystem.out.println("Sum: " + sum);} }class StaticVariableExample {static int count = 0; // 静态变量public StaticVariableExample() {count++;}public static int getCount() {return count;} }
总结
- 变量的声明:指定变量的名称和数据类型。
- 变量的初始化:给变量赋一个初始值,可以在声明时或声明后进行。
- 变量的作用域:
- 局部变量:在方法、构造方法或块中声明,作用域仅限于声明它们的方法、构造方法或块内。
- 实例变量:在类中声明但在方法、构造方法或块之外声明,每个对象有自己的副本。
- 静态变量:在类中使用
static
关键字声明,所有对象共享同一个变量。- 参数变量:在方法声明中作为参数传递,作用域仅限于方法内部。
运算符:算术、比较、逻辑、位操作等。
1. 算术运算符(Arithmetic Operators)
算术运算符用于执行基本的数学运算。
- 加法 (
+
):将两个操作数相加。- 减法 (
-
):将第二个操作数从第一个操作数中减去。- 乘法 (
*
):将两个操作数相乘。- 除法 (
/
):将第一个操作数除以第二个操作数。- 取模 (
%
):返回两个操作数相除后的余数。- 自增 (
++
):将操作数的值增加1。- 自减 (
--
):将操作数的值减少1。示例:
int a = 10; int b = 3;int sum = a + b; // 13 int difference = a - b; // 7 int product = a * b; // 30 int quotient = a / b; // 3 int remainder = a % b; // 1a++; // a 现在是 11 b--; // b 现在是 2
2. 比较运算符(Comparison Operators)
比较运算符用于比较两个操作数的值,结果为布尔值(
true
或false
)。
- 等于 (
==
):检查两个操作数是否相等。- 不等于 (
!=
):检查两个操作数是否不相等。- 大于 (
>
):检查第一个操作数是否大于第二个操作数。- 小于 (
<
):检查第一个操作数是否小于第二个操作数。- 大于等于 (
>=
):检查第一个操作数是否大于或等于第二个操作数。- 小于等于 (
<=
):检查第一个操作数是否小于或等于第二个操作数。示例:
int a = 10; int b = 3;boolean isEqual = a == b; // false boolean isNotEqual = a != b; // true boolean isGreater = a > b; // true boolean isLess = a < b; // false boolean isGreaterOrEqual = a >= b; // true boolean isLessOrEqual = a <= b; // false
3. 逻辑运算符(Logical Operators)
逻辑运算符用于组合多个条件表达式,结果为布尔值。
- 逻辑与 (
&&
):如果两个操作数都为true
,则结果为true
。- 逻辑或 (
||
):如果两个操作数中至少有一个为true
,则结果为true
。- 逻辑非 (
!
):反转操作数的布尔值。示例:
boolean a = true; boolean b = false;boolean andResult = a && b; // false boolean orResult = a || b; // true boolean notResult = !a; // false
4. 位运算符(Bitwise Operators)
位运算符用于对整数的二进制形式进行操作。
- 按位与 (
&
):对两个操作数的每一位进行与操作。- 按位或 (
|
):对两个操作数的每一位进行或操作。- 按位异或 (
^
):对两个操作数的每一位进行异或操作。- 按位非 (
~
):对操作数的每一位进行取反操作。- 左移 (
<<
):将操作数的二进制位向左移动指定的位数。- 右移 (
>>
):将操作数的二进制位向右移动指定的位数,高位补符号位。- 无符号右移 (
>>>
):将操作数的二进制位向右移动指定的位数,高位补0。示例:
int a = 60; // 0011 1100 int b = 13; // 0000 1101int andResult = a & b; // 0000 1100 = 12 int orResult = a | b; // 0011 1101 = 61 int xorResult = a ^ b; // 0011 0001 = 49 int notResult = ~a; // 1100 0011 = -61 (补码表示) int leftShift = a << 2;// 1111 0000 = 240 int rightShift = a >> 2;// 0000 1111 = 15 int unsignedRightShift = a >>> 2;// 0000 1111 = 15
5. 赋值运算符(Assignment Operators)
赋值运算符用于将值赋给变量。
- 简单赋值 (
=
):将右边的值赋给左边的变量。- 复合赋值运算符:结合了算术运算符和赋值运算符,简化赋值操作。
+=
:加法赋值-=
:减法赋值*=
:乘法赋值/=
:除法赋值%=
:取模赋值&=
:按位与赋值|=
:按位或赋值^=
:按位异或赋值<<=
:左移赋值>>=
:右移赋值>>>=
:无符号右移赋值示例:
int a = 10;a += 5; // a = a + 5; a 现在是 15 a -= 3; // a = a - 3; a 现在是 12 a *= 2; // a = a * 2; a 现在是 24 a /= 4; // a = a / 4; a 现在是 6 a %= 5; // a = a % 5; a 现在是 1
6. 条件运算符(Conditional Operator)
条件运算符是一种三元运算符,用于根据条件选择不同的值。
- 条件运算符 (
? :
):如果条件为true
,则返回第一个表达式的值;否则返回第二个表达式的值。示例:
int a = 10; int b = 20;int max = (a > b) ? a : b; // max 现在是 20
7. 其他运算符
- 类型转换运算符 (
(type)
):将一个类型转换为另一个类型。- 逗号运算符(
,
):在一个表达式中顺序执行多个操作,返回最后一个表达式的值。- 成员访问运算符(
.
):用于访问对象的属性和方法。- 数组访问运算符(
[]
):用于访问数组的元素。示例:
int a = 10; double b = (double) a; // b 现在是 10.0int result = (1, 2, 3); // result 现在是 3class Person {String name;int age; }Person person = new Person(); person.name = "Alice"; person.age = 30;int[] numbers = {1, 2, 3, 4, 5}; int firstElement = numbers[0]; // firstElement 现在是 1
总结
- 算术运算符:用于基本的数学运算。
- 比较运算符:用于比较两个操作数的值。
- 逻辑运算符:用于组合多个条件表达式。
- 位运算符:用于对整数的二进制形式进行操作。
- 赋值运算符:用于将值赋给变量。
- 条件运算符:用于根据条件选择不同的值。
- 其他运算符:包括类型转换、逗号、成员访问和数组访问运算符。
流程控制语句
1. 条件语句
if 语句
if
语句用于根据条件的真假来决定是否执行某段代码。语法:
if (condition) {// 条件为 true 时执行的代码 } else {// 条件为 false 时执行的代码 }
示例:
int age = 20; if (age >= 18) {System.out.println("你已经成年了。"); } else {System.out.println("你还未成年。"); }
switch 语句
switch
语句用于多分支选择,根据变量的值来执行不同的代码块。语法:
switch (expression) {case value1:// 当 expression 等于 value1 时执行的代码break;case value2:// 当 expression 等于 value2 时执行的代码break;// 可以有多个 casedefault:// 当 expression 不等于任何一个 case 值时执行的代码 }
示例:
int day = 3; switch (day) {case 1:System.out.println("星期一");break;case 2:System.out.println("星期二");break;case 3:System.out.println("星期三");break;case 4:System.out.println("星期四");break;case 5:System.out.println("星期五");break;case 6:System.out.println("星期六");break;case 7:System.out.println("星期日");break;default:System.out.println("无效的天数"); }
2. 循环语句
for 语句
for
语句用于重复执行一段代码,直到满足某个条件为止。语法:
for (initialization; condition; increment/decrement) {// 循环体 }
示例:
for (int i = 1; i <= 5; i++) {System.out.println("i 的值是: " + i); }
while 语句
while
语句用于在条件为真时重复执行一段代码。语法:
while (condition) {// 循环体 }
示例:
int i = 1; while (i <= 5) {System.out.println("i 的值是: " + i);i++; }
do-while 语句
do-while
语句至少执行一次循环体,然后再判断条件是否为真。语法:
do {// 循环体 } while (condition);
示例:
int i = 1; do {System.out.println("i 的值是: " + i);i++; } while (i <= 5);
3. 跳转语句
break 语句
break
语句用于立即退出循环或switch
语句。示例:
for (int i = 1; i <= 10; i++) {if (i == 5) {break; // 当 i 等于 5 时退出循环}System.out.println("i 的值是: " + i); }
continue 语句
continue
语句用于跳过当前循环的剩余部分,直接进入下一次循环。示例:
for (int i = 1; i <= 10; i++) {if (i % 2 == 0) {continue; // 当 i 是偶数时跳过本次循环}System.out.println("i 的值是: " + i); }
return 语句
return
语句用于从方法中返回,可以带有一个返回值(如果方法有返回类型)。示例:
public int add(int a, int b) {int result = a + b;return result; // 返回结果 }public void printMessage() {System.out.println("Hello, World!");return; // 无返回值的方法也可以使用 return 语句 }
总结
以上是 Java 中常用的流程控制语句,包括条件语句(
if
和switch
)、循环语句(for
、while
和do-while
)以及跳转语句(break
、continue
和return
)。掌握这些语句是编写复杂逻辑和控制程序流程的基础。
数组:一维数组、多维数组、数组遍历
1. 一维数组
一维数组是最简单的数组形式,用于存储一列相同类型的元素。
声明和初始化
声明:
dataType[] arrayName;
初始化:
arrayName = new dataType[arraySize];
或者在声明时直接初始化:
dataType[] arrayName = new dataType[arraySize];
也可以直接赋值:
dataType[] arrayName = {element1, element2, ..., elementN};
示例:
int[] numbers; // 声明 numbers = new int[5]; // 初始化// 或者一步完成声明和初始化 int[] numbers = new int[5];// 直接赋值 int[] numbers = {1, 2, 3, 4, 5};
访问和修改元素
数组索引从 0 开始,最后一个元素的索引是
array.length - 1
。示例:
int[] numbers = {1, 2, 3, 4, 5};// 访问元素 int firstElement = numbers[0]; // 1 int lastElement = numbers[numbers.length - 1]; // 5// 修改元素 numbers[2] = 10; // 将第三个元素修改为 10
遍历一维数组
使用 for 循环:
int[] numbers = {1, 2, 3, 4, 5};for (int i = 0; i < numbers.length; i++) {System.out.println(numbers[i]); }
使用增强 for 循环(foreach):
int[] numbers = {1, 2, 3, 4, 5};for (int number : numbers) {System.out.println(number); }
2. 多维数组
多维数组可以看作是数组的数组,最常见的是二维数组。
声明和初始化
声明:
dataType[][] arrayName;
初始化:
arrayName = new dataType[rows][columns];
或者在声明时直接初始化:
dataType[][] arrayName = new dataType[rows][columns];
也可以直接赋值:
dataType[][] arrayName = {{element11, element12, ...}, {element21, element22, ...}, ...};
示例:
int[][] matrix; // 声明 matrix = new int[3][3]; // 初始化// 或者一步完成声明和初始化 int[][] matrix = new int[3][3];// 直接赋值 int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9} };
访问和修改元素
示例:
int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9} };// 访问元素 int firstElement = matrix[0][0]; // 1 int lastElement = matrix[matrix.length - 1][matrix[0].length - 1]; // 9// 修改元素 matrix[1][1] = 10; // 将第二行第二列的元素修改为 10
遍历多维数组
使用嵌套 for 循环:
int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9} };for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println(); }
使用增强 for 循环(foreach):
int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9} };for (int[] row : matrix) {for (int element : row) {System.out.print(element + " ");}System.out.println(); }
总结
- 一维数组:用于存储一列相同类型的元素,可以通过索引访问和修改元素,支持使用普通 for 循环和增强 for 循环进行遍历。
- 多维数组:可以看作是数组的数组,最常见的是二维数组,可以通过嵌套索引访问和修改元素,支持使用嵌套 for 循环和嵌套增强 for 循环进行遍历。
三、面向对象编程
1. 定义类
类是对象的模板,用于描述对象的属性和行为。
示例:
public class Person {// 属性(字段)private String name;private int age;// 构造器public Person(String name, int age) {this.name = name;this.age = age;}// 方法public void sayHello() {System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");}// Getter 和 Setter 方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
2. 创建对象
通过
new
关键字创建类的实例(对象)。示例:
public class Main {public static void main(String[] args) {Person person = new Person("Alice", 30);person.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.} }
3. 构造器
构造器用于在创建对象时初始化对象的状态。
示例:
public class Person {private String name;private int age;// 无参构造器public Person() {this.name = "Unknown";this.age = 0;}// 带参数的构造器public Person(String name, int age) {this.name = name;this.age = age;} }
4. 访问修饰符
访问修饰符控制类、方法和字段的可见性。
- public:公开,任何地方都可以访问。
- protected:受保护,同一包内的类或子类可以访问。
- 默认(无修饰符):包内可见。
- private:私有,仅在本类内可见。
示例:
public class Person {private String name; // 私有字段protected int age; // 受保护字段public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
继承
继承允许一个类继承另一个类的属性和方法。
1. extends 关键字
使用
extends
关键字实现继承。示例:
public class Student extends Person {private String studentId;public Student(String name, int age, String studentId) {super(name, age); // 调用父类的构造器this.studentId = studentId;}public String getStudentId() {return studentId;}public void setStudentId(String studentId) {this.studentId = studentId;}@Overridepublic void sayHello() {System.out.println("Hello, my name is " + getName() + ", I am " + getAge() + " years old, and my student ID is " + studentId);} }
2. super 关键字
super
关键字用于调用父类的构造器或方法。示例:
public class Student extends Person {private String studentId;public Student(String name, int age, String studentId) {super(name, age); // 调用父类的构造器this.studentId = studentId;}@Overridepublic void sayHello() {super.sayHello(); // 调用父类的方法System.out.println("My student ID is " + studentId);} }
3. 方法重写
子类可以重写父类的方法,以提供不同的实现。
示例:
public class Student extends Person {private String studentId;public Student(String name, int age, String studentId) {super(name, age);this.studentId = studentId;}@Overridepublic void sayHello() {System.out.println("Hello, my name is " + getName() + ", I am " + getAge() + " years old, and my student ID is " + studentId);} }
封装
封装是将数据(属性)和操作数据的方法绑定在一起,并隐藏对象的内部实现细节。
1. private 访问修饰符
使用
private
修饰符隐藏类的内部实现。示例:
public class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
2. getters 和 setters 方法
提供公共方法来访问和修改私有字段。
示例:
public class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
多态
多态允许子类对象被当作父类对象使用。
1. 接口实现
接口定义了一组方法,但没有具体实现,类通过实现接口来提供具体实现。
示例:
public interface Animal {void makeSound(); }public class Dog implements Animal {@Overridepublic void makeSound() {System.out.println("Woof!");} }public class Cat implements Animal {@Overridepublic void makeSound() {System.out.println("Meow!");} }public class Main {public static void main(String[] args) {Animal dog = new Dog();Animal cat = new Cat();dog.makeSound(); // 输出: Woof!cat.makeSound(); // 输出: Meow!} }
2. 抽象类
抽象类不能被实例化,但可以包含抽象方法和具体方法。
示例:
public abstract class Animal {public abstract void makeSound();public void eat() {System.out.println("Eating...");} }public class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("Woof!");} }public class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("Meow!");} }public class Main {public static void main(String[] args) {Animal dog = new Dog();Animal cat = new Cat();dog.makeSound(); // 输出: Woof!dog.eat(); // 输出: Eating...cat.makeSound(); // 输出: Meow!cat.eat(); // 输出: Eating...} }
3. 方法覆盖
子类可以覆盖父类的方法,提供不同的实现。
示例:
public class Animal {public void makeSound() {System.out.println("Some sound...");} }public class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("Woof!");} }public class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("Meow!");} }public class Main {public static void main(String[] args) {Animal dog = new Dog();Animal cat = new Cat();dog.makeSound(); // 输出: Woof!cat.makeSound(); // 输出: Meow!} }
接口
接口定义了一组方法,但没有具体实现,类通过实现接口来提供具体实现。
1. 定义接口
示例:
public interface Animal {void makeSound(); }
2. 实现接口
示例:
public class Dog implements Animal {@Overridepublic void makeSound() {System.out.println("Woof!");} }public class Cat implements Animal {@Overridepublic void makeSound() {System.out.println("Meow!");} }
内部类
内部类是在另一个类内部定义的类。
1. 成员内部类
成员内部类是定义在另一个类内部的非静态类。
示例:
public class OuterClass {private String outerField = "Outer Field";public class InnerClass {public void display() {System.out.println(outerField);}} }public class Main {public static void main(String[] args) {OuterClass outer = new OuterClass();OuterClass.InnerClass inner = outer.new InnerClass();inner.display(); // 输出: Outer Field} }
2. 局部内部类
局部内部类是在方法或作用域内定义的类。
示例:
public class OuterClass {private String outerField = "Outer Field";public void display() {class LocalInnerClass {public void show() {System.out.println(outerField);}}LocalInnerClass localInner = new LocalInnerClass();localInner.show(); // 输出: Outer Field} }public class Main {public static void main(String[] args) {OuterClass outer = new OuterClass();outer.display();} }
3. 匿名内部类
匿名内部类是没有名字的内部类,通常用于创建一次性使用的对象。
示例:
public class Main {public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("Running...");}};Thread thread = new Thread(runnable);thread.start();} }
4. 静态内部类
静态内部类是定义在另一个类内部的静态类,可以独立于外部类实例存在。
示例:
public class OuterClass {private String outerField = "Outer Field";public static class StaticInnerClass {public void display() {// 不能直接访问外部类的非静态字段// System.out.println(outerField);System.out.println("Static Inner Class");}} }public class Main {public static void main(String[] args) {OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();staticInner.display(); // 输出: Static Inner Class} }
总结
- 类和对象:类是对象的蓝图,对象是类的实例。
- 继承:使用
extends
关键字实现继承,super
关键字调用父类的构造器或方法,子类可以重写父类的方法。- 封装:使用
private
修饰符隐藏类的内部实现,提供getters
和setters
方法访问和修改私有字段。- 多态:子类对象可以被当作父类对象使用,接口和抽象类是实现多态的重要手段。
- 接口:定义了一组方法,类通过实现接口来提供具体实现。
- 内部类:成员内部类、局部内部类、匿名内部类和静态内部类,每种内部类有不同的用途和特点。
四、异常处理
1. 什么是异常
异常是指在程序执行过程中发生的意外情况,这些情况会中断程序的正常执行流程。Java 提供了异常处理机制来捕获和处理这些意外情况,从而使程序能够继续运行或优雅地终止。
2. 异常分类
Java 中的异常主要分为两大类:
- Checked Exception(受检异常):在编译时检查的异常,必须进行处理或声明抛出。例如
IOException
、SQLException
等。- Unchecked Exception(非受检异常):在运行时检查的异常,通常是编程错误导致的,例如
NullPointerException
、ArrayIndexOutOfBoundsException
等。此外,还有一种特殊的异常类型:
- Error:表示严重的错误,通常是无法恢复的情况,例如
OutOfMemoryError
、StackOverflowError
等。这些错误通常不由应用程序处理。异常处理机制
1. try-catch
try-catch
语句用于捕获和处理异常。语法:
try {// 可能会抛出异常的代码 } catch (ExceptionType1 e1) {// 处理 ExceptionType1 的代码 } catch (ExceptionType2 e2) {// 处理 ExceptionType2 的代码 } finally {// 无论是否发生异常都会执行的代码 }
示例:
public class Main {public static void main(String[] args) {try {int[] numbers = {1, 2, 3};System.out.println(numbers[5]); // 会抛出 ArrayIndexOutOfBoundsException} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组索引越界: " + e.getMessage());} finally {System.out.println("finally 块总是会被执行");}} }
2. finally
finally
块中的代码无论是否发生异常都会被执行,通常用于释放资源。示例:
public class Main {public static void main(String[] args) {try {int[] numbers = {1, 2, 3};System.out.println(numbers[5]); // 会抛出 ArrayIndexOutOfBoundsException} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组索引越界: " + e.getMessage());} finally {System.out.println("finally 块总是会被执行");}} }
3. throw
throw
关键字用于手动抛出一个异常。示例:
public class Main {public static void main(String[] args) {try {throw new IllegalArgumentException("这是一个非法参数异常");} catch (IllegalArgumentException e) {System.out.println("捕获到异常: " + e.getMessage());}} }
4. throws
throws
关键字用于声明一个方法可能会抛出的异常,调用该方法时需要处理这些异常。示例:
import java.io.IOException;public class Main {public static void main(String[] args) {try {readFile("example.txt");} catch (IOException e) {System.out.println("文件读取失败: " + e.getMessage());}}public static void readFile(String fileName) throws IOException {// 模拟文件读取操作if (!fileName.endsWith(".txt")) {throw new IOException("文件格式不正确");}System.out.println("文件读取成功: " + fileName);} }
自定义异常
自定义异常是通过继承
Exception
类或其子类来创建的。自定义异常可以帮助你更好地描述特定的错误情况。1. 创建自定义异常类
示例:
public class CustomException extends Exception {public CustomException(String message) {super(message);} }
2. 使用自定义异常
示例:
public class Main {public static void main(String[] args) {try {validateAge(15);} catch (CustomException e) {System.out.println("捕获到自定义异常: " + e.getMessage());}}public static void validateAge(int age) throws CustomException {if (age < 18) {throw new CustomException("年龄必须大于或等于 18 岁");}System.out.println("年龄验证通过");} }
总结
- 异常概念:异常是在程序执行过程中发生的意外情况,Java 提供了异常处理机制来捕获和处理这些情况。
- 异常分类:异常分为受检异常和非受检异常,以及严重的错误(Error)。
- 异常处理机制:
try-catch
:捕获和处理异常。finally
:无论是否发生异常都会执行的代码块。throw
:手动抛出一个异常。throws
:声明一个方法可能会抛出的异常。- 自定义异常:通过继承
Exception
类或其子类来创建自定义异常,以便更好地描述特定的错误情况。
五、 高级特性
1. 泛型类
泛型类允许在类声明时指定类型参数,从而在实例化时指定具体的类型。
示例:
public class Box<T> {private T item;public Box(T item) {this.item = item;}public T getItem() {return item;}public void setItem(T item) {this.item = item;} }public class Main {public static void main(String[] args) {Box<String> stringBox = new Box<>("Hello");System.out.println(stringBox.getItem()); // 输出: HelloBox<Integer> intBox = new Box<>(123);System.out.println(intBox.getItem()); // 输出: 123} }
2. 泛型方法
泛型方法允许在方法声明时指定类型参数。
示例:
public class Util {public static <T> void printArray(T[] array) {for (T element : array) {System.out.println(element);}} }public class Main {public static void main(String[] args) {Integer[] intArray = {1, 2, 3, 4, 5};Util.printArray(intArray);String[] stringArray = {"Hello", "World"};Util.printArray(stringArray);} }
3. 泛型接口
泛型接口允许在接口声明时指定类型参数。
示例:
public interface Box<T> {void add(T item);T get(); }public class IntegerBox implements Box<Integer> {private Integer item;@Overridepublic void add(Integer item) {this.item = item;}@Overridepublic Integer get() {return item;} }public class Main {public static void main(String[] args) {Box<Integer> box = new IntegerBox();box.add(123);System.out.println(box.get()); // 输出: 123} }
集合框架
1. List 接口及其实现类
List
接口表示有序集合,允许重复元素。实现类:
ArrayList
LinkedList
Vector
示例:
import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("Apple");list.add("Banana");list.add("Cherry");for (String fruit : list) {System.out.println(fruit);}} }
2. Set 接口及其实现类
Set
接口表示无序集合,不允许重复元素。实现类:
HashSet
LinkedHashSet
TreeSet
示例:
import java.util.HashSet; import java.util.Set;public class Main {public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("Apple");set.add("Banana");set.add("Cherry");set.add("Apple"); // 重复元素不会被添加for (String fruit : set) {System.out.println(fruit);}} }
3. Map 接口及其实现类
Map
接口表示键值对集合,键是唯一的。实现类:
HashMap
LinkedHashMap
TreeMap
示例:
import java.util.HashMap; import java.util.Map;public class Main {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();map.put("Apple", 1);map.put("Banana", 2);map.put("Cherry", 3);for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}} }
IO 流
1. File 类
File
类用于表示文件和目录路径。示例:
import java.io.File;public class Main {public static void main(String[] args) {File file = new File("example.txt");if (file.exists()) {System.out.println("文件存在");} else {System.out.println("文件不存在");}} }
2. InputStream/OutputStream
InputStream
和OutputStream
是字节流的基类。示例:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;public class Main {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("input.txt");FileOutputStream fos = new FileOutputStream("output.txt")) {int content;while ((content = fis.read()) != -1) {fos.write(content);}} catch (IOException e) {e.printStackTrace();}} }
3. Reader/Writer
Reader
和Writer
是字符流的基类。示例:
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;public class Main {public static void main(String[] args) {try (FileReader fr = new FileReader("input.txt");FileWriter fw = new FileWriter("output.txt")) {int content;while ((content = fr.read()) != -1) {fw.write(content);}} catch (IOException e) {e.printStackTrace();}} }
多线程
1. Thread 类
Thread
类用于创建和管理线程。示例:
public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程运行中: " + Thread.currentThread().getName());} }public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();} }
2. Runnable 接口
Runnable
接口用于实现多线程。示例:
public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("线程运行中: " + Thread.currentThread().getName());} }public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();} }
3. 线程同步
使用
synchronized
关键字确保线程安全。示例:
public class Counter {private int count = 0;public synchronized void increment() {count++;}public synchronized int getCount() {return count;} }public class Main {public static void main(String[] args) {final Counter counter = new Counter();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数: " + counter.getCount()); // 输出: 最终计数: 2000} }
4. 锁
使用
Lock
接口和ReentrantLock
类进行更细粒度的锁控制。示例:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class Counter {private int count = 0;private final Lock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}public int getCount() {return count;} }public class Main {public static void main(String[] args) {final Counter counter = new Counter();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数: " + counter.getCount()); // 输出: 最终计数: 2000} }
网络编程
1. Socket 编程
使用
Socket
和ServerSocket
进行网络通信。服务器端:
import java.io.*; import java.net.*;public class Server {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(12345)) {System.out.println("服务器已启动,等待客户端连接...");Socket socket = serverSocket.accept();System.out.println("客户端已连接");BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(), true);String inputLine;while ((inputLine = in.readLine()) != null) {System.out.println("收到消息: " + inputLine);out.println("Echo: " + inputLine);}} catch (IOException e) {e.printStackTrace();}} }
客户端:
import java.io.*; import java.net.*;public class Client {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 12345)) {BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(), true);out.println("Hello, Server");String response = in.readLine();System.out.println("服务器响应: " + response);} catch (IOException e) {e.printStackTrace();}} }
2. URL 连接
使用
URL
和URLConnection
进行网络请求。示例:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection;public class Main {public static void main(String[] args) {try {URL url = new URL("http://example.com");URLConnection connection = url.openConnection();BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String inputLine;while ((inputLine = in.readLine()) != null) {System.out.println(inputLine);}in.close();} catch (Exception e) {e.printStackTrace();}} }
反射
1. Class 对象
Class
对象表示类的运行时信息。示例:
public class Main {public static void main(String[] args) {Class<?> clazz = String.class;System.out.println("类名: " + clazz.getName());} }
2. 获取类信息
使用反射获取类的信息,如构造器、方法、字段等。
示例:
import java.lang.reflect.Constructor; import java.lang.reflect.Method;public class Main {public static void main(String[] args) {Class<?> clazz = String.class;Constructor<?>[] constructors = clazz.getDeclaredConstructors();for (Constructor<?> constructor : constructors) {System.out.println("构造器: " + constructor);}Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println("方法: " + method);}} }
3. 创建对象
使用反射创建对象。
示例:
public class Main {public static void main(String[] args) {try {Class<?> clazz = String.class;Constructor<?> constructor = clazz.getConstructor(String.class);String str = (String) constructor.newInstance("Hello, Reflection");System.out.println(str);} catch (Exception e) {e.printStackTrace();}} }
4. 调用方法
使用反射调用方法。
示例:
public class Main {public static void main(String[] args) {try {Class<?> clazz = String.class;Method method = clazz.getMethod("toUpperCase");String str = "hello";String upperCaseStr = (String) method.invoke(str);System.out.println(upperCaseStr);} catch (Exception e) {e.printStackTrace();}} }
注解
1. 内置注解
Java 提供了一些内置注解,如
@Override
、@Deprecated
、@SuppressWarnings
等。示例:
public class Main {@Overridepublic String toString() {return "Main{}";}@Deprecatedpublic void oldMethod() {System.out.println("这是个过时的方法");}@SuppressWarnings("unused")private void unusedMethod() {System.out.println("这个方法未被使用");}public static void main(String[] args) {Main main = new Main();main.oldMethod();} }
2. 元注解
元注解用于注解其他注解,如
@Retention
、@Target
、@Documented
、@Inherited
等。示例:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation {String value() default ""; }
3. 自定义注解
自定义注解用于特定的业务需求。
示例:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation {String value() default ""; }public class Main {@MyAnnotation(value = "这是一个自定义注解")public void annotatedMethod() {System.out.println("带有注解的方法");}public static void main(String[] args) {Main main = new Main();main.annotatedMethod();Class<Main> clazz = Main.class;Method method = clazz.getMethod("annotatedMethod");MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);if (annotation != null) {System.out.println("注解值: " + annotation.value());}} }
总结
- 泛型:允许在类、方法和接口中使用类型参数,提高代码的复用性和类型安全性。
- 集合框架:提供了多种集合类,如
List
、Set
和Map
,用于存储和操作数据。- IO 流:提供了文件和数据流的读写功能,包括字节流和字符流。
- 多线程:通过
Thread
类和Runnable
接口实现多线程,使用synchronized
和Lock
进行线程同步。- 网络编程:通过
Socket
和ServerSocket
进行网络通信,使用URL
和URLConnection
进行网络请求。- 反射:允许在运行时获取类的信息,动态创建对象和调用方法。
- 注解:用于标记类、方法和字段,提供元数据信息,包括内置注解、元注解和自定义注解。
六、标准库
日期和时间
1. Date
Date
类表示特定的瞬间,精确到毫秒。示例:
import java.util.Date;public class Main {public static void main(String[] args) {Date date = new Date();System.out.println("当前日期和时间: " + date);} }
2. Calendar
Calendar
类提供了更丰富的日期和时间操作功能。示例:
import java.util.Calendar;public class Main {public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println("当前年份: " + calendar.get(Calendar.YEAR));System.out.println("当前月份: " + (calendar.get(Calendar.MONTH) + 1)); // 月份从0开始System.out.println("当前日期: " + calendar.get(Calendar.DAY_OF_MONTH));} }
3. LocalDate, LocalDateTime, LocalTime
Java 8 引入了新的日期和时间 API,包括
LocalDate
、LocalDateTime
和LocalTime
,提供了更强大和易用的功能。示例:
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter;public class Main {public static void main(String[] args) {LocalDate currentDate = LocalDate.now();System.out.println("当前日期: " + currentDate);LocalTime currentTime = LocalTime.now();System.out.println("当前时间: " + currentTime);LocalDateTime currentDateTime = LocalDateTime.now();System.out.println("当前日期和时间: " + currentDateTime);// 格式化日期和时间DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String formattedDateTime = currentDateTime.format(formatter);System.out.println("格式化后的日期和时间: " + formattedDateTime);// 解析日期和时间LocalDateTime parsedDateTime = LocalDateTime.parse(formattedDateTime, formatter);System.out.println("解析后的日期和时间: " + parsedDateTime);} }
正则表达式
1. Pattern 和 Matcher
Pattern
和Matcher
类用于处理正则表达式。示例:
import java.util.regex.Matcher; import java.util.regex.Pattern;public class Main {public static void main(String[] args) {String text = "Hello, my email is example@example.com";String regex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(text);while (matcher.find()) {System.out.println("找到匹配的电子邮件: " + matcher.group());}} }
国际化
1. ResourceBundle
ResourceBundle
类用于加载语言资源文件,支持多语言应用。示例:
import java.util.Locale; import java.util.ResourceBundle;public class Main {public static void main(String[] args) {Locale locale = new Locale("en", "US");ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);System.out.println("欢迎信息: " + bundle.getString("welcome.message"));} }
资源文件示例:
messages_en_US.properties
:welcome.message=Welcome to our application!
messages_zh_CN.properties
:welcome.message=欢迎使用我们的应用!
2. Locale
Locale
类表示特定的地理、政治和文化区域。示例:
import java.util.Locale;public class Main {public static void main(String[] args) {Locale locale = new Locale("zh", "CN");System.out.println("语言: " + locale.getLanguage());System.out.println("国家: " + locale.getCountry());} }
并发工具
1. ExecutorService
ExecutorService
是一个高级线程管理工具,用于管理和调度线程。示例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class Main {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);executorService.submit(() -> {System.out.println("任务 1 在运行: " + Thread.currentThread().getName());});executorService.submit(() -> {System.out.println("任务 2 在运行: " + Thread.currentThread().getName());});executorService.shutdown();} }
2. Future 和 Callable
Callable
接口用于返回结果的任务,Future
用于获取异步任务的结果。示例:
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;public class Main {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();Future<Integer> future = executorService.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {Thread.sleep(2000);return 42;}});try {Integer result = future.get();System.out.println("任务结果: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}executorService.shutdown();} }
3. Lock 和 Condition
Lock
接口提供了比synchronized
更强大的锁机制,Condition
用于线程间的协作。示例:
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class Main {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition condition = lock.newCondition();Thread producer = new Thread(() -> {lock.lock();try {System.out.println("生产者准备生产...");condition.signal();} finally {lock.unlock();}});Thread consumer = new Thread(() -> {lock.lock();try {System.out.println("消费者等待生产...");condition.await();System.out.println("消费者开始消费...");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}});consumer.start();producer.start();} }
总结
- 日期和时间:
Date
和Calendar
用于基本的日期和时间操作,Java 8 引入了LocalDate
、LocalDateTime
和LocalTime
,提供了更强大的日期和时间功能。- 正则表达式:
Pattern
和Matcher
类用于处理正则表达式,进行字符串匹配和替换。- 国际化:
ResourceBundle
和Locale
类用于支持多语言应用,加载和管理语言资源文件。- 并发工具:
ExecutorService
用于管理和调度线程,Future
和Callable
用于返回结果的任务,Lock
和Condition
提供了更强大的锁机制和线程间协作。
七、框架与工具
构建工具
1. Maven
Maven 是一个项目管理和构建自动化工具,基于项目对象模型(POM)。它使用 XML 文件(
pom.xml
)来管理项目的构建、依赖关系和文档。示例:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>my-app</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build> </project>
2. Gradle
Gradle 是一个基于 Groovy 或 Kotlin 脚本的构建工具,提供了更灵活的构建配置和更好的性能。
示例:
build.gradle
apply plugin: 'java' apply plugin: 'application'mainClassName = 'com.example.Main'repositories {mavenCentral() }dependencies {testImplementation 'junit:junit:4.12' }tasks.withType(JavaCompile) {options.encoding = 'UTF-8'options.compilerArgs << '-parameters' }
测试框架
1. JUnit
JUnit 是一个流行的单元测试框架,支持编写和运行单元测试。
示例:
import org.junit.Test; import static org.junit.Assert.assertEquals;public class CalculatorTest {@Testpublic void testAdd() {Calculator calculator = new Calculator();int result = calculator.add(2, 3);assertEquals(5, result);} }class Calculator {public int add(int a, int b) {return a + b;} }
2. TestNG
TestNG 是一个功能更强大的测试框架,支持单元测试、集成测试和功能测试。
示例:
import org.testng.annotations.Test; import static org.testng.Assert.assertEquals;public class CalculatorTest {@Testpublic void testAdd() {Calculator calculator = new Calculator();int result = calculator.add(2, 3);assertEquals(result, 5);} }class Calculator {public int add(int a, int b) {return a + b;} }
Web 开发
1. Servlet
Servlet 是 Java Web 应用的基础,用于处理 HTTP 请求和响应。
示例:
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;public class HelloWorldServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<h1>Hello, World!</h1>");} }
web.xml 配置:
<web-app><servlet><servlet-name>HelloWorldServlet</servlet-name><servlet-class>com.example.HelloWorldServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloWorldServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping> </web-app>
2. JSP
JSP(JavaServer Pages)是一种动态网页技术,允许在 HTML 页面中嵌入 Java 代码。
示例:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>Hello, JSP</title> </head> <body><h1>Hello, JSP!</h1><p>Current time: <%= new java.util.Date() %></p> </body> </html>
3. Spring
Spring 是一个轻量级的 Java 开发框架,提供了依赖注入、事务管理、AOP 等功能。
示例:
Application.java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;@SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@RestControllerpublic class HelloController {@GetMapping("/hello")public String hello() {return "Hello, Spring!";}} }
4. Hibernate
Hibernate 是一个对象关系映射(ORM)框架,用于将 Java 对象映射到数据库表。
示例:
User.java
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;@Entity public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String email;// Getters and Setters }
配置文件:
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration><session-factory><property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">password</property><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><property name="hibernate.hbm2ddl.auto">update</property><mapping class="com.example.User"/></session-factory> </hibernate-configuration>
GUI 开发
1. Swing
Swing 是一个用于创建图形用户界面(GUI)的 Java 库,提供了丰富的组件和事件处理机制。
示例:
import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class HelloWorldSwing {public static void main(String[] args) {JFrame frame = new JFrame("Hello, Swing!");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(300, 200);JButton button = new JButton("Click Me");button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JOptionPane.showMessageDialog(frame, "Button Clicked!");}});frame.getContentPane().add(button);frame.setVisible(true);} }
2. JavaFX
JavaFX 是一个用于创建富客户端应用程序的现代 GUI 库,提供了更丰富的图形和媒体支持。
示例:
HelloWorldJavaFX.java
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage;public class HelloWorldJavaFX extends Application {@Overridepublic void start(Stage primaryStage) {Button button = new Button("Click Me");button.setOnAction(event -> {System.out.println("Button Clicked!");});StackPane root = new StackPane();root.getChildren().add(button);Scene scene = new Scene(root, 300, 200);primaryStage.setTitle("Hello, JavaFX!");primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);} }
总结
构建工具:
- Maven:基于 XML 的项目管理和构建工具。
- Gradle:基于 Groovy 或 Kotlin 脚本的构建工具,提供更灵活的配置和更好的性能。
测试框架:
- JUnit:流行的单元测试框架。
- TestNG:功能更强大的测试框架,支持多种测试类型。
Web 开发:
- Servlet:处理 HTTP 请求和响应的基础技术。
- JSP:动态网页技术,允许在 HTML 中嵌入 Java 代码。
- Spring:轻量级开发框架,提供依赖注入、事务管理等功能。
- Hibernate:对象关系映射(ORM)框架,用于将 Java 对象映射到数据库表。
GUI 开发:
- Swing:用于创建图形用户界面的库,提供丰富的组件和事件处理机制。
- JavaFX:现代的 GUI 库,提供更丰富的图形和媒体支持。
八、最佳实践
代码规范
1. 命名规则
- 类名:首字母大写的驼峰式命名,例如
Calculator
。- 方法名:首字母小写的驼峰式命名,例如
calculateSum
。- 变量名:首字母小写的驼峰式命名,例如
totalAmount
。- 常量名:全部大写,单词之间用下划线分隔,例如
MAX_VALUE
。- 包名:全小写,通常使用公司域名的倒序,例如
com.example.myapp
。2. 代码格式化
- 缩进:通常使用 4 个空格或 1 个制表符。
- 行长度:每行不超过 80 到 120 个字符。
- 大括号:始终使用大括号,即使只有一行代码。
- 空行:合理使用空行,提高代码可读性。
- 注释:使用 Javadoc 风格的注释,对类、方法和重要逻辑进行说明。
示例:
package com.example.myapp;/*** 计算器类*/ public class Calculator {/*** 计算两个数的和** @param a 第一个数* @param b 第二个数* @return 两数之和*/public int calculateSum(int a, int b) {return a + b;} }
设计模式
1. 单例模式
确保一个类只有一个实例,并提供一个全局访问点。
示例:
public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}public void doSomething() {System.out.println("Singleton instance doing something.");} }
2. 工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
示例:
public interface Animal {void makeSound(); }public class Dog implements Animal {@Overridepublic void makeSound() {System.out.println("Bark");} }public class Cat implements Animal {@Overridepublic void makeSound() {System.out.println("Meow");} }public class AnimalFactory {public static Animal createAnimal(String type) {if ("dog".equalsIgnoreCase(type)) {return new Dog();} else if ("cat".equalsIgnoreCase(type)) {return new Cat();} else {throw new IllegalArgumentException("Unknown animal type");}} }public class FactoryPatternDemo {public static void main(String[] args) {Animal dog = AnimalFactory.createAnimal("dog");dog.makeSound();Animal cat = AnimalFactory.createAnimal("cat");cat.makeSound();} }
3. 装饰者模式
动态地给一个对象添加一些额外的职责,而不影响其他对象。
示例:
public interface Coffee {String getDescription();double getCost(); }public class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double getCost() {return 1.0;} }public abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee c) {this.decoratedCoffee = c;}@Overridepublic String getDescription() {return decoratedCoffee.getDescription();}@Overridepublic double getCost() {return decoratedCoffee.getCost();} }public class MilkCoffee extends CoffeeDecorator {public MilkCoffee(Coffee c) {super(c);}@Overridepublic String getDescription() {return super.getDescription() + ", Milk";}@Overridepublic double getCost() {return super.getCost() + 0.5;} }public class SugarCoffee extends CoffeeDecorator {public SugarCoffee(Coffee c) {super(c);}@Overridepublic String getDescription() {return super.getDescription() + ", Sugar";}@Overridepublic double getCost() {return super.getCost() + 0.2;} }public class DecoratorPatternDemo {public static void main(String[] args) {Coffee coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " Cost: " + coffee.getCost());coffee = new MilkCoffee(coffee);System.out.println(coffee.getDescription() + " Cost: " + coffee.getCost());coffee = new SugarCoffee(coffee);System.out.println(coffee.getDescription() + " Cost: " + coffee.getCost());} }
性能优化
1. 内存管理
- 避免内存泄漏:及时释放不再使用的对象引用。
- 使用合适的数据结构:选择合适的数据结构可以减少内存占用。
- 对象池:复用对象,减少频繁的创建和销毁。
2. JVM 调优
- 垃圾回收:调整垃圾回收器参数,例如
-XX:+UseG1GC
。- 堆大小:设置合适的堆大小,例如
-Xms512m -Xmx1024m
。- JVM 参数:根据应用需求调整其他 JVM 参数,例如
-XX:MaxPermSize=256m
。示例: 启动参数
java -Xms512m -Xmx1024m -XX:+UseG1GC -jar myapp.jar
安全性
1. 输入验证
- 验证用户输入:确保输入符合预期格式,例如使用正则表达式。
- 使用安全的输入库:例如 Apache Commons Lang 的
StringUtils
。示例:
import java.util.regex.Pattern;public class InputValidator {private static final Pattern EMAIL_PATTERN = Pattern.compile("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");public boolean isValidEmail(String email) {return EMAIL_PATTERN.matcher(email).matches();} }
2. 防止 SQL 注入
- 使用预编译语句:避免直接拼接 SQL 语句。
- 使用 ORM 框架:例如 Hibernate,自动处理 SQL 注入问题。
示例:
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;public class SqlInjectionPrevention {public void insertUser(Connection conn, String username, String password) throws SQLException {String sql = "INSERT INTO users (username, password) VALUES (?, ?)";try (PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, username);pstmt.setString(2, password);pstmt.executeUpdate();}} }
3. 使用安全的 API
- 加密敏感数据:使用
javax.crypto
包中的类进行加密。- 安全的网络通信:使用 HTTPS 而不是 HTTP。
示例:
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; import java.util.Base64;public class SecurityExample {private static final String ALGORITHM = "AES";public static SecretKey generateKey() throws Exception {KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);SecureRandom random = new SecureRandom();keyGen.init(128, random);return keyGen.generateKey();}public static byte[] encrypt(String data, SecretKey key) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data.getBytes());}public static String decrypt(byte[] encryptedData, SecretKey key) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key);byte[] decryptedData = cipher.doFinal(encryptedData);return new String(decryptedData);}public static void main(String[] args) throws Exception {SecretKey key = generateKey();String originalData = "Sensitive Data";byte[] encryptedData = encrypt(originalData, key);String decryptedData = decrypt(encryptedData, key);System.out.println("Original: " + originalData);System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encryptedData));System.out.println("Decrypted: " + decryptedData);} }
总结
- 代码规范:遵循命名规则和代码格式化标准,提高代码可读性和可维护性。
- 设计模式:使用单例模式、工厂模式和装饰者模式等设计模式,提高代码的灵活性和可扩展性。
- 性能优化:通过内存管理和 JVM 调优,提升应用的性能。
- 安全性:通过输入验证、防止 SQL 注入和使用安全的 API,确保应用的安全性。