目录
LocalDate, LocalTime, LocalDateTime
BufferedReader 和 BufferedWriter
1. 引言
Java 的背景
Java 的起源及历史发展
Java 于 1995 年由 Sun Microsystems 发布,最初由詹姆斯·高斯林(James Gosling)领导的团队开发。最初的目标是为家用电器和电子设备提供一种可移植的编程语言,但随着互联网的兴起,Java 在网络应用开发中找到了广阔的应用空间。
主要的应用场景
- Web 开发:借助于 Java Servlets、JavaServer Pages (JSP) 和 JavaServer Faces (JSF) 等技术,Java 在服务器端 Web 开发中占有重要地位。
- 移动应用:Android 应用程序主要使用 Java 编写,Android SDK 基于 Java 开发。
- 大数据:Hadoop、Spark 等大数据处理框架大量使用 Java 语言。
Java 的核心特性
面向对象
Java 是一种 纯面向对象 的编程语言,支持封装、继承、多态和抽象等面向对象的基本特性。所有的代码都必须写在类中,即使是基本类型也有对应的包装类。
跨平台性(JVM 的角色)
Java 的口号是 "Write Once, Run Anywhere"(一次编写,到处运行)。这得益于 Java 虚拟机(JVM),它将 Java 代码编译成与平台无关的字节码,然后由 JVM 解释执行。这使得 Java 程序可以在任何安装了 JVM 的设备上运行。
自动内存管理与垃圾回收机制
Java 提供了自动垃圾回收机制(Garbage Collection),开发者无需手动管理内存分配和释放。这有效地减少了内存泄漏和指针错误等问题,提高了程序的稳定性和安全性。
Java 版本与发展历程
Java SE 8, 11, 17 等主要版本特性
- Java SE 8:
- 引入了 Lambda 表达式 和 Stream API,大大简化了集合的操作。
- 增加了 默认方法,接口可以有默认实现。
- Java SE 11:
- 新的 HttpClient API,替代了原有的 HttpURLConnection。
- 局部变量类型推断(var)的增强。
- Java SE 17:
- 引入了 Sealed Classes(密封类),允许更严格地控制继承关系。
- Pattern Matching(模式匹配)的改进。
新增功能概述(如 Lambda 表达式、模块系统)
- Lambda 表达式:提供了函数式编程的能力,使代码更加简洁。
- 模块系统:从 Java 9 开始,引入了模块化系统(Project Jigsaw),支持更好的封装和依赖管理。
2. Java 基础语法
变量与数据类型
原始数据类型
Java 有八种原始数据类型,每种类型都有固定的内存大小和默认值。
数据类型 | 内存大小 | 默认值 | 范围 |
---|---|---|---|
byte | 1 字节 | 0 | -128 到 127 |
short | 2 字节 | 0 | -32,768 到 32,767 |
int | 4 字节 | 0 | -2^31 到 2^31 -1 |
long | 8 字节 | 0L | -2^63 到 2^63 -1 |
float | 4 字节 | 0.0f | 约 ±3.40282347E+38F (~7 位) |
double | 8 字节 | 0.0d | 约 ±1.79769313486231570E+308 |
boolean | 1 位 | false | true 或 false |
char | 2 字节 | '\u0000' | 0 到 65,535 |
示例:变量声明和初始化
int age = 25;
double price = 19.99;
char grade = 'A';
boolean isMember = true;
引用数据类型
- 类:用户定义的类型,包括属性和方法。
- 接口:定义了类需要实现的方法。
- 数组:存储同类型元素的集合。
- 字符串:
String
类,表示字符序列。
示例:引用类型的使用
String name = "Alice";
int[] numbers = {1, 2, 3, 4, 5};
运算符
算术运算符
- 加法:
+
- 减法:
-
- 乘法:
*
- 除法:
/
- 取模:
%
示例:
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; // 1
关系运算符
- 大于:
>
- 小于:
<
- 等于:
==
- 不等于:
!=
- 大于等于:
>=
- 小于等于:
<=
示例:
boolean result = (a > b); // true
逻辑运算符
- 逻辑与:
&&
- 逻辑或:
||
- 逻辑非:
!
示例:
boolean isAdult = (age >= 18) && (age < 65);
运算符优先级和结合性
优先级 | 运算符 | 结合性 |
---|---|---|
1 | () | 从左到右 |
2 | ! 、~ | 从右到左 |
3 | * 、/ 、% | 从左到右 |
4 | + 、- | 从左到右 |
5 | > 、< 、>= 、<= | 从左到右 |
6 | == 、!= | 从左到右 |
7 | && | 从左到右 |
8 | ` | |
9 | = 、+= 、-= 等 | 从右到左 |
控制结构
条件语句
if-else 语句
if (condition) {
// 当条件为真时执行
} else {
// 当条件为假时执行
}
switch 语句
switch (variable) {
case value1:
// 代码块
break;
case value2:
// 代码块
break;
default:
// 默认代码块
}
示例:
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 75) {
System.out.println("良好");
} else {
System.out.println("及格");
}
循环结构
for 循环
for (int i = 0; i < 10; i++) {
// 循环体
}
while 循环
while (condition) {
// 循环体
}
do-while 循环
do {
// 循环体
} while (condition);
示例:
// 打印 1 到 5
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
条件语句和循环的适用场景
结构 | 适用场景 |
---|---|
if-else | 条件判断,执行不同的代码块 |
switch | 多个固定值的比较 |
for | 已知循环次数的情况 |
while | 循环次数未知,但满足条件时继续循环 |
do-while | 至少执行一次循环体,再判断条件 |
数组
一维数组
声明和初始化
int[] numbers = new int[5];
int[] scores = {90, 85, 70, 95, 80};
遍历数组
for (int i = 0; i < scores.length; i++) {
System.out.println(scores[i]);
}
多维数组
声明和初始化
int[][] matrix = new int[3][3]; int[][] data = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
遍历二维数组
for (int i = 0; i < data.length; i++) { for (int j = 0; j < data[i].length; j++) { System.out.print(data[i][j] + " "); } System.out.println(); }
3. 面向对象编程(OOP)
类与对象
类的定义
public class Person { // 属性(成员变量) private String name; private int age; // 构造方法 public Person(String name, int age) { this.name = name; this.age = age; } // 方法(行为) public void introduce() { System.out.println("大家好,我叫 " + name + ",今年 " + age + " 岁。"); } }
对象的创建
Person person = new Person("Alice", 25); person.introduce();
封装
访问控制修饰符
- public:对所有类可见。
- private:仅对本类可见。
- protected:对本类、子类和同一包内的类可见。
- 默认(不写):对同一包内的类可见。
getter 和 setter 方法
public class Person { private String name; private int age; // Getter 方法 public String getName() { return name; } // Setter 方法 public void setName(String name) { this.name = name; } // 同理为 age 添加 getter 和 setter }
示例:
Person person = new Person(); person.setName("Bob"); System.out.println(person.getName());
继承
继承的概念
子类继承父类的属性和方法,可以重用代码并增加新的功能。
public class Animal { public void eat() { System.out.println("动物在吃东西"); } } public class Dog extends Animal { public void bark() { System.out.println("狗在汪汪叫"); } }
super 关键字
用于调用父类的构造方法或方法。
public class Dog extends Animal { public Dog() { super(); // 调用父类的构造方法 } @Override public void eat() { super.eat(); // 调用父类的方法 System.out.println("狗在吃骨头"); } }
示例:
Dog dog = new Dog(); dog.eat(); // 输出:动物在吃东西 \n 狗在吃骨头 dog.bark(); // 输出:狗在汪汪叫
继承与多态的实现对比
特性 | 实现方式 | 优点 |
---|---|---|
继承 | 使用 extends 关键字 | 代码重用,建立层次结构 |
多态 | 方法重写、接口的实现 | 提高代码的灵活性和可扩展性 |
多态
方法重载与重写
- 方法重载:同一类中方法名相同,参数列表不同。
- 方法重写:子类重新定义父类的方法,方法签名相同。
示例:方法重载
public class Calculator { public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } }
示例:方法重写
public class Animal { public void makeSound() { System.out.println("动物发出声音"); } } public class Cat extends Animal { @Override public void makeSound() { System.out.println("猫在喵喵叫"); } }
多态的应用
Animal animal = new Cat(); animal.makeSound(); // 输出:猫在喵喵叫
接口与抽象类
接口的定义与实现
定义接口
public interface Movable { void move(); }
实现接口
public class Car implements Movable { @Override public void move() { System.out.println("汽车在行驶"); } }
抽象类
定义抽象类
public abstract class Shape { public abstract double getArea(); }
继承抽象类
public class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } }
接口与抽象类的区别
比较项 | 接口 | 抽象类 |
---|---|---|
默认方法 | Java 8 之后可以有默认方法 | 可以有具体方法 |
构造方法 | 没有构造方法 | 可以有构造方法 |
多继承 | 一个类可以实现多个接口 | 一个类只能继承一个抽象类 |
适用场景 | 定义规范,强调做什么 | 定义模板,强调怎么做 |
示例:
// 接口实现 public interface Flyable { void fly(); } public class Bird implements Flyable { @Override public void fly() { System.out.println("鸟在飞翔"); } } // 抽象类继承 public abstract class Vehicle { public abstract void run(); } public class Bicycle extends Vehicle { @Override public void run() { System.out.println("自行车在行驶"); } }
4. Java 内置类与库
常用类
String 类
字符串创建
String str = "Hello, World!";
常用方法
- 长度:
str.length()
- 连接:
str.concat(" Welcome!")
- 截取:
str.substring(0, 5)
- 替换:
str.replace('l', 'p')
示例:
String greeting = "Hello"; String name = "Alice"; String message = greeting + ", " + name + "!"; System.out.println(message); // 输出:Hello, Alice!
Math 类
常用方法
- 取整:
Math.floor()
,Math.ceil()
,Math.round()
- 随机数:
Math.random()
- 最大/最小值:
Math.max(a, b)
,Math.min(a, b)
- 指数/对数:
Math.pow(a, b)
,Math.log(a)
示例:
double randomNumber = Math.random(); // 生成 0.0 到 1.0 之间的随机数 int max = Math.max(10, 20); // 20
常用方法与用途总结
类 | 方法 | 用途 |
---|---|---|
String | length() | 获取字符串长度 |
String | charAt(index) | 获取指定位置的字符 |
String | equals(str) | 比较字符串内容 |
Math | abs(a) | 取绝对值 |
Math | sqrt(a) | 求平方根 |
集合框架
Java 集合框架提供了一组用来存储和操作数据的接口和类。
List 接口
ArrayList
- 动态数组,支持随机访问。
- 适合读多写少的场景。
LinkedList
- 双向链表,增删速度快。
- 适合频繁插入和删除的场景。
示例:
List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); System.out.println(list.get(0)); // 输出:Apple
Set 接口
HashSet
- 不允许重复元素,无序。
- 基于哈希表实现。
TreeSet
- 不允许重复元素,有序。
- 基于红黑树实现。
示例:
Set<Integer> set = new HashSet<>(); set.add(1); set.add(2); set.add(1); // 重复元素,不会添加 System.out.println(set.size()); // 输出:2
Map 接口
HashMap
- 键值对存储,键不可重复。
- 无序,线程不安全。
TreeMap
- 键值对存储,按键排序。
- 基于红黑树实现。
示例:
Map<String, Integer> map = new HashMap<>(); map.put("Apple", 3); map.put("Banana", 2); System.out.println(map.get("Apple")); // 输出:3
List、Set、Map 的区别与对比
接口 | 特点 | 是否允许重复 | 是否有序 |
---|---|---|---|
List | 有序集合,按插入顺序 | 允许 | 是 |
Set | 无序集合,不允许重复元素 | 不允许 | 否(HashSet) |
Map | 键值对存储 | 键不允许重复 | 视实现而定 |
Java 时间与日期 API
Java 8 引入了新的日期和时间 API,更加易用和安全。
LocalDate, LocalTime, LocalDateTime
获取当前日期和时间
LocalDate date = LocalDate.now(); LocalTime time = LocalTime.now(); LocalDateTime dateTime = LocalDateTime.now();
指定日期和时间
LocalDate specificDate = LocalDate.of(2021, 12, 31); LocalTime specificTime = LocalTime.of(23, 59, 59);
日期和时间操作
LocalDate tomorrow = date.plusDays(1); LocalTime nextHour = time.plusHours(1);
DateTimeFormatter
格式化日期和时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDateTime = dateTime.format(formatter); System.out.println(formattedDateTime); // 输出:2021-08-20 14:30:00
Java 8 时间 API 常用类和方法总结
类 | 用途 |
---|---|
LocalDate | 表示日期(年、月、日) |
LocalTime | 表示时间(时、分、秒) |
LocalDateTime | 表示日期和时间 |
DateTimeFormatter | 格式化日期和时间 |
文件 I/O 操作
File 类
用于表示文件或目录的信息,但不涉及文件内容的读写。
File file = new File("test.txt"); if (file.exists()) { System.out.println("文件存在"); }
BufferedReader 和 BufferedWriter
用于高效地读写文本文件。
读取文件
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); }
写入文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { writer.write("Hello, World!"); } catch (IOException e) { e.printStackTrace(); }
I/O 类的对比与应用场景
类 | 用途 |
---|---|
FileReader | 读取字符文件 |
FileWriter | 写入字符文件 |
BufferedReader | 提高读取效率,支持 readLine() |
BufferedWriter | 提高写入效率 |
FileInputStream | 读取字节文件 |
FileOutputStream | 写入字节文件 |
通过以上内容,我们详细介绍了 Java 的基础知识,从基本语法到面向对象编程,再到常用的内置类与库。每个部分都配有示例代码和总结表格,帮助读者更好地理解和掌握 Java 编程的核心概念。