1. Java语言概述与核心特性
Java作为一门诞生于1995年的编程语言,至今仍保持着强大的生命力。它的设计初衷是"一次编写,到处运行"(Write Once, Run Anywhere),这一理念通过Java虚拟机(JVM)得以实现。不同于C/C++等需要针对不同操作系统编译的语言,Java源代码会被编译成字节码(bytecode),然后在JVM上运行,这使得Java程序具有出色的跨平台能力。
Java的核心特性可以概括为以下几个方面:
-
面向对象:Java是纯粹的面向对象语言,所有代码都必须包含在类中(即使是简单的main方法)。它支持封装、继承和多态这三大面向对象特性,并提供了接口、抽象类等机制来实现更灵活的代码组织。
-
自动内存管理:通过垃圾回收(Garbage Collection)机制自动管理内存,开发者不需要像在C/C++中那样手动分配和释放内存,这大大减少了内存泄漏的风险。
-
强类型系统:Java是静态强类型语言,所有变量都必须先声明类型才能使用,这有助于在编译期发现类型错误,提高代码的健壮性。
-
异常处理机制:Java提供了完善的异常处理机制,通过try-catch-finally结构可以优雅地处理运行时错误,避免程序意外终止。
-
丰富的标准库:Java自带庞大的标准库(Java Standard Library),涵盖了从基础数据结构(集合框架)、IO操作、网络编程到并发处理等各个方面。
-
安全性:Java在设计时就考虑了安全性,包括字节码验证、安全管理器等机制,可以有效防止恶意代码的执行。
提示:虽然Java的自动内存管理减轻了开发者的负担,但理解JVM的内存模型和垃圾回收机制对于编写高性能Java应用仍然至关重要。
2. Java开发环境搭建与配置
2.1 JDK安装与环境变量配置
要开始Java开发,首先需要安装Java Development Kit(JDK)。JDK包含了Java运行时环境(JRE)和开发工具(如编译器javac)。以下是详细的安装步骤:
-
下载JDK:从Oracle官网或OpenJDK项目获取适合你操作系统的JDK版本。目前长期支持版(LTS)包括Java 8、11和17。
-
安装JDK:
- Windows:运行下载的exe安装程序,记住安装路径(如C:\Program Files\Java\jdk-17)
- macOS:使用pkg安装包或Homebrew(
brew install openjdk@17) - Linux:使用包管理器(如Ubuntu的
apt install openjdk-17-jdk)
-
配置环境变量:
- 设置
JAVA_HOME指向JDK安装目录 - 将
%JAVA_HOME%\bin添加到PATH环境变量中
- 设置
验证安装是否成功:
bash复制java -version
javac -version
2.2 常见安装问题解决
在实际安装过程中,可能会遇到以下典型问题:
-
版本不匹配警告:"警告: 源发行版17需要目标发行版17"
- 原因:编译器版本与运行环境版本不一致
- 解决:确保IDE中的Java编译级别与项目使用的JDK版本一致
-
Lombok兼容性问题:"you aren't using a compiler supported by lombok"
- 原因:使用的编译器不被Lombok支持
- 解决:在IDE中启用注解处理(Annotation Processing),或更新Lombok版本
-
内存不足错误:"OutOfMemoryError: Insufficient memory"
- 原因:JVM分配的内存不足
- 解决:通过
-Xmx参数增加最大堆内存,如java -Xmx2g MyApp
3. Java基础语法核心要点
3.1 数据类型与变量
Java的数据类型分为两大类:基本类型和引用类型。
基本类型:
- 整型:byte(1字节), short(2), int(4), long(8)
- 浮点型:float(4), double(8)
- 字符型:char(2)
- 布尔型:boolean(理论上是1位,实际实现依赖JVM)
引用类型:
- 类类型(如String)
- 接口类型
- 数组类型
变量声明示例:
java复制int count = 10; // 基本类型
String name = "Java"; // 引用类型
int[] numbers = {1,2,3}; // 数组类型
3.2 运算符与表达式
Java支持丰富的运算符,按功能可分为:
- 算术运算符:+ - * / % ++ --
- 关系运算符:> < >= <= == !=
- 逻辑运算符:&& || !
- 位运算符:& | ^ ~ << >> >>>
- 赋值运算符:= += -= *= /= %= &= |= ^= <<= >>= >>>=
- 条件运算符:? :
- instanceof运算符:检查对象是否是特定类的实例
特殊运算符注意事项:
/运算符在整数运算中会截断小数部分%可以用于浮点数(如7.5%2.1=1.2)==比较引用类型时比较的是引用而非内容(字符串比较应该用equals())
3.3 控制流程
Java提供了标准的控制流程语句:
- 条件语句:
java复制if (condition) {
// ...
} else if (anotherCondition) {
// ...
} else {
// ...
}
- switch语句(Java 12+支持表达式形式):
java复制int day = 3;
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid";
};
- 循环语句:
java复制// for循环
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
// 增强for循环(foreach)
int[] numbers = {1, 2, 3};
for (int num : numbers) {
System.out.println(num);
}
// while循环
while (condition) {
// ...
}
// do-while循环
do {
// ...
} while (condition);
4. 面向对象编程核心概念
4.1 类与对象
类是Java程序的基本构建块,定义了一类对象的属性和行为。对象是类的实例。
java复制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("Hello, I'm " + name + ", " + age + " years old.");
}
// Getter和Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4.2 继承与多态
继承允许类继承另一个类的特性,实现代码复用。Java使用extends关键字实现单继承。
java复制public class Student extends Person {
private String school;
public Student(String name, int age, String school) {
super(name, age); // 调用父类构造方法
this.school = school;
}
@Override
public void introduce() {
super.introduce();
System.out.println("I study at " + school);
}
}
多态允许子类对象被视为父类类型,但在运行时表现出子类的行为:
java复制Person p = new Student("Alice", 20, "Harvard");
p.introduce(); // 调用的是Student的introduce方法
4.3 接口与抽象类
接口定义了一组方法规范,Java 8以后接口可以包含默认方法和静态方法:
java复制public interface Drawable {
void draw(); // 抽象方法
default void resize() { // 默认方法
System.out.println("Resizing...");
}
static void printInfo() { // 静态方法
System.out.println("This is a drawable object");
}
}
抽象类是不能被实例化的类,可以包含抽象方法和具体方法:
java复制public abstract class Shape {
private String color;
public Shape(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public abstract double area(); // 抽象方法
public void display() { // 具体方法
System.out.println("Color: " + color);
}
}
注意:从Java 8开始,接口和抽象类的区别变得模糊。一般规则是:当需要定义类型的行为规范时使用接口,当需要提供部分实现时使用抽象类。
5. Java集合框架与常用工具类
5.1 集合框架概述
Java集合框架(Java Collections Framework)提供了一套性能优良、使用方便的接口和类,位于java.util包中。主要接口包括:
-
Collection:所有集合类的根接口
- List:有序集合,允许重复(ArrayList, LinkedList)
- Set:不包含重复元素的集合(HashSet, TreeSet)
- Queue:队列,通常但不一定遵循FIFO原则(LinkedList, PriorityQueue)
-
Map:键值对集合(HashMap, TreeMap)
集合框架类关系图:
code复制Collection
├── List
│ ├── ArrayList
│ └── LinkedList
├── Set
│ ├── HashSet
│ └── TreeSet
└── Queue
├── LinkedList
└── PriorityQueue
Map
├── HashMap
└── TreeMap
5.2 常用集合类使用示例
ArrayList(动态数组):
java复制List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add(1, "C++"); // 在索引1处插入
for (String lang : list) {
System.out.println(lang);
}
HashMap(哈希表):
java复制Map<String, Integer> map = new HashMap<>();
map.put("Apple", 10);
map.put("Banana", 5);
System.out.println(map.get("Apple")); // 输出10
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
5.3 工具类
Arrays:提供操作数组的各种方法
java复制int[] numbers = {3, 1, 4, 1, 5, 9};
Arrays.sort(numbers); // 排序
System.out.println(Arrays.toString(numbers)); // 数组转字符串
Collections:提供操作集合的各种方法
java复制List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4));
Collections.sort(list); // 排序
Collections.reverse(list); // 反转
6. 异常处理与IO操作
6.1 Java异常体系
Java异常分为两大类:
- Checked Exception:必须处理的异常(IOException, SQLException等)
- Unchecked Exception:RuntimeException及其子类(NullPointerException, ArrayIndexOutOfBoundsException等)
异常处理基本结构:
java复制try {
// 可能抛出异常的代码
FileInputStream fis = new FileInputStream("file.txt");
} catch (FileNotFoundException e) {
// 处理特定异常
System.err.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
// 处理更一般的异常
System.err.println("IO错误: " + e.getMessage());
} finally {
// 无论是否发生异常都会执行的代码
System.out.println("清理资源...");
}
Java 7引入了try-with-resources语句,简化资源管理:
java复制try (FileInputStream fis = new FileInputStream("file.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
6.2 文件IO操作
Java通过java.io和java.nio包提供文件操作支持:
传统IO(java.io):
java复制// 写入文件
try (FileWriter writer = new FileWriter("output.txt")) {
writer.write("Hello, Java IO!");
}
// 读取文件
try (BufferedReader reader = new BufferedReader(new FileReader("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
NIO(java.nio):
java复制Path path = Paths.get("output.txt");
try {
// 读取所有行
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
System.out.println(line);
}
// 写入文件
Files.write(path, "New content".getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
7. 多线程与并发编程
7.1 线程基础
Java中创建线程的两种主要方式:
- 继承Thread类:
java复制class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread running: " + getName());
}
}
// 使用
MyThread thread = new MyThread();
thread.start();
- 实现Runnable接口(推荐,因为Java不支持多继承):
java复制class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
7.2 线程同步与锁
当多个线程访问共享资源时,需要使用同步机制避免竞态条件:
synchronized关键字:
java复制class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
ReentrantLock(更灵活的锁):
java复制class Counter {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
7.3 并发工具类
Java并发包(java.util.concurrent)提供了强大的并发工具:
ExecutorService(线程池):
java复制ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
System.out.println("Task executed by " + Thread.currentThread().getName());
});
}
executor.shutdown();
CountDownLatch(同步辅助类):
java复制CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Thread finished work");
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("All threads finished");
8. Java新特性与最佳实践
8.1 Java 8+重要新特性
Lambda表达式:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((a, b) -> a.compareTo(b)); // 使用Lambda表达式
Stream API:
java复制List<String> filtered = names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.collect(Collectors.toList());
Optional类(避免NullPointerException):
java复制Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("Default");
记录类(Record)(Java 14+):
java复制public record Point(int x, int y) {}
// 自动生成构造方法、equals、hashCode、toString等
8.2 Java编码最佳实践
-
遵循命名规范:
- 类名:大驼峰(MyClass)
- 方法/变量:小驼峰(myMethod)
- 常量:全大写加下划线(MAX_VALUE)
-
合理使用访问修饰符:
- 优先使用private,只在必要时放宽访问权限
- 考虑使用final修饰不应被修改的类、方法和变量
-
异常处理原则:
- 不要捕获异常后什么都不做(空的catch块)
- 优先处理特定异常,而不是捕获通用的Exception
- 考虑使用自定义异常来表达业务错误
-
资源管理:
- 总是使用try-with-resources管理需要关闭的资源
- 避免在finally块中抛出异常
-
并发编程建议:
- 优先使用并发工具类而不是直接使用线程
- 考虑使用不可变对象来避免同步问题
- 使用线程池而不是直接创建线程
提示:在实际项目中,除了掌握语言特性外,还需要熟悉常用的开发工具和框架,如构建工具(Maven/Gradle)、单元测试(JUnit)、日志框架(SLF4J/Log4j2)等,这些工具能显著提高开发效率和代码质量。
