后端开发基础(二)- Java基础
前言
Java 是一种高级、面向对象的编程语言,以其可移植性、健壮性和可扩展性而闻名。 Java 由 Sun Microsystems(现为 Oracle)开发,遵循”一次编写,随处运行”的原则,允许代码在任何具有 Java 虚拟机 (JVM) 的设备上运行。它广泛用于构建大型企业应用程序、Android 移动应用程序和 Web 服务。 Java 具有自动内存管理(垃圾收集)、庞大的标准库和强大的安全功能,使其成为后端系统、分布式应用程序和基于云的解决方案的流行选择。学习 Java 语言也是为之后深入学习企业常用的后端开发框架 SSM 打好基础。
学习路线
1. 环境准备
JDK安装与配置
- 了解JDK、JRE和JVM的区别与关系
- 选择适合的JDK版本(如LTS版本:JDK 8、JDK 11、JDK 17)
- 下载与安装JDK
- 配置JAVA_HOME、PATH等环境变量
- 验证安装成功(使用java -version命令)
开发工具选择
- Eclipse IDE:安装、配置插件和工作空间设置
- IntelliJ IDEA:社区版vs专业版、安装和基本设置
- VS Code:安装Java扩展包和配置
- 熟悉IDE的基本功能:代码提示、断点调试、快捷键等
- 版本控制工具集成(Git)
编写第一个程序
- 了解Java程序的基本结构(类、方法、包)
- 编写并运行Hello World程序
- 理解main方法的作用和参数
- 熟悉编译和运行的过程(javac和java命令)
- 掌握基本的程序调试方法
2. Java语法基础
基本语法
- 标识符:命名规则和命名约定
- 关键字:Java预留的关键字及其用途
- 注释:单行注释、多行注释、文档注释(Javadoc)
- 基本数据类型:整型(byte、short、int、long)、浮点型(float、double)、字符型(char)、布尔型(boolean)
- 类型转换:自动类型转换和强制类型转换
- 字面量:整数、浮点数、字符、字符串、布尔字面量
变量与常量
- 变量声明和初始化语法
- 局部变量、成员变量、静态变量的区别
- 变量作用域和生命周期
- 常量(final)的定义和使用
- 命名规范与最佳实践
运算符
- 算术运算符:+、-、*、/、%、++、–
- 关系运算符:==、!=、>、<、>=、<=
- 逻辑运算符:&&、||、!
- 位运算符:&、|、^、~、<<、>>、>>>
- 赋值运算符:=、+=、-=、*=、/=等
- 条件运算符(三元运算符):? :
- 运算符优先级和结合性
控制流
- 条件语句
- if语句:简单if、if-else、if-else if-else
- switch语句:基本用法、支持的数据类型、fall-through特性
- 循环语句
- for循环:标准for循环、增强for循环(for-each)
- while循环:前测试循环
- do-while循环:后测试循环
- 跳转语句
- break:跳出循环或switch
- continue:跳过当前循环
- return:从方法返回
- 带标签的break和continue
- 循环嵌套与控制技巧
数组
- 一维数组:声明、创建、初始化
- 数组索引和元素访问
- 数组长度和遍历方法
- 多维数组:二维数组及更高维度
- 不规则数组(锯齿形数组)
- Arrays工具类基本使用:排序、查找、填充、比较等
- 数组常见算法:查找、排序、合并、复制等
3. 面向对象编程
类与对象
- 类的定义:结构和语法
- 对象的创建与使用:new关键字
- 构造方法:默认构造器、带参构造器
- 构造方法重载和链式调用(this())
- 对象引用和内存模型
- 垃圾回收机制和finalize方法
- 对象比较:==和equals方法
三大特性
- 封装
- 访问控制与信息隐藏
- getter和setter方法
- 封装的意义和最佳实践
- 继承
- extends关键字和继承语法
- 父类和子类关系
- 方法继承和覆盖
- 构造方法与继承:super()
- 继承的限制(final类等)
- 多层继承与继承层次
- 多态
- 向上转型与向下转型
- 运行时多态vs编译时多态
- 动态绑定机制
- instanceof操作符和类型检查
- 多态的实际应用场景
成员变量与方法
- 实例变量:声明、初始化、访问
- 类变量(静态变量):static关键字
- 实例方法:定义和调用
- 静态方法:定义和限制
- 方法参数:值传递vs引用传递
- 方法重载(Overloading):规则和用例
- 方法重写(Overriding):规则和注意事项
- 可变参数方法(varargs)
访问修饰符
- public:完全公开
- protected:包内和子类可见
- default(无修饰符):包内可见
- private:仅类内可见
- 修饰符的适用范围:类、方法、字段
- 封装中的访问控制选择原则
- 多个修饰符组合使用
抽象类与接口
- 抽象类
- abstract关键字
- 抽象方法与具体方法
- 抽象类的继承规则
- 何时使用抽象类
- 接口
- interface定义语法
- 接口中的方法和常量
- 接口实现:implements关键字
- 多接口实现
- 接口继承:extends关键字
- 默认方法和静态方法(Java 8+)
- 函数式接口(@FunctionalInterface)
- 抽象类vs接口:选择指南
内部类
- 静态内部类:定义和使用
- 非静态内部类(成员内部类):定义、使用和外部类引用
- 局部内部类:方法内定义的类
- 匿名内部类:没有名字的内部类
- 内部类的应用场景和访问规则
- 嵌套内部类和继承关系
- Lambda表达式与匿名内部类的关系
4. Java核心类
Object类
- Object作为所有类的基类
- toString()方法:默认实现和重写
- equals()方法:相等性判断和重写规则
- hashCode()方法:散列码生成和equals/hashCode契约
- getClass()方法:获取运行时类信息
- clone()方法:对象克隆和Cloneable接口
- finalize()方法:对象销毁前的清理(已弃用)
- wait()、notify()、notifyAll():线程协作
String类
- 字符串的不可变性及其意义
- 字符串创建:字面量vs new
- 字符串池(String Pool)机制
- 常用方法:
- 字符串比较:equals(), equalsIgnoreCase(), compareTo()
- 查找和检索:indexOf(), lastIndexOf(), contains(), startsWith(), endsWith()
- 提取子串:substring(), split()
- 转换:toLowerCase(), toUpperCase(), trim(), replace(), replaceAll()
- 格式化:format()
- StringBuffer和StringBuilder:可变字符串
- 字符串连接性能优化
- 字符串常见操作和算法
包装类
- 基本数据类型的包装类:Integer, Double, Character, Boolean等
- 自动装箱和自动拆箱
- 数值类型转换:parseXxx()和valueOf()方法
- 包装类的常用方法和常量
- 包装类与字符串的相互转换
- 包装类的缓存机制(如Integer缓存)
- 包装类的比较注意事项
日期与时间
- 传统日期时间API
- Date类:创建和格式化
- Calendar类:日期计算和字段操作
- SimpleDateFormat:日期格式化和解析
- Java 8新日期时间API
- LocalDate:日期表示
- LocalTime:时间表示
- LocalDateTime:日期和时间
- ZonedDateTime:带时区的日期时间
- Period和Duration:时间段表示
- DateTimeFormatter:格式化和解析
- TemporalAdjusters:日期调整器
- 日期时间计算和操作
- 时区处理
- 日期比较和排序
数学运算
- Math类常用方法:
- 基本数学函数:abs(), sqrt(), pow(), log()
- 取整函数:ceil(), floor(), round()
- 最大值和最小值:max(), min()
- 随机数:random()
- BigInteger:大整数运算
- BigDecimal:精确十进制运算
- 常用数学算法和计算
- 随机数生成:Random类
- 数学常量:PI, E等
5. 异常处理
异常体系
- Throwable类层次结构
- Error:不可恢复的系统错误
- 常见Error类型:OutOfMemoryError, StackOverflowError等
- Exception:可处理的程序异常
- 受检异常(Checked Exception):必须处理的异常
- 非受检异常(Unchecked Exception/RuntimeException):可以不显式处理
- 常见的异常类型及其原因
- NullPointerException
- ArrayIndexOutOfBoundsException
- ClassCastException
- IllegalArgumentException
- IOException等
异常捕获与处理
- try-catch基本语法
- 多catch块处理不同异常
- catch顺序和异常继承关系
- finally块:无论异常是否发生都执行的代码
- try-with-resources语句(Java 7+):自动资源管理
- 异常链:getCause()和initCause()
- 多重捕获(Java 7+):catch (ExceptionA | ExceptionB e)
- 异常处理最佳实践
异常抛出
- throws声明:方法可能抛出的异常
- throw语句:手动抛出异常
- 异常传播机制:调用栈中的异常传递
- 何时抛出vs何时捕获异常
- 异常文档和注释(@throws JavaDoc标记)
- 重写方法中的异常声明规则
自定义异常
- 创建自定义异常类:继承Exception或RuntimeException
- 异常构造方法和消息
- 添加额外信息到自定义异常
- 异常设计原则和最佳实践
- 业务异常vs技术异常
- 异常转换:将底层异常包装为更有意义的高层异常
6. 集合框架
Collection接口
- Collection接口基本方法:add(), remove(), contains(), size(), isEmpty()等
- List接口及实现
- ArrayList:基于动态数组的实现
- LinkedList:基于双向链表的实现
- Vector:线程安全的动态数组(较少使用)
- 各实现类的性能特征和适用场景
- 常用操作:添加、删除、查找、遍历、排序
- Set接口及实现
- HashSet:基于HashMap的实现
- LinkedHashSet:保持插入顺序的HashSet
- TreeSet:基于TreeMap的有序集合
- 无重复元素和相等性判断
- 常用操作和性能考虑
- Queue和Deque接口
- LinkedList作为队列和双端队列
- PriorityQueue:优先级队列
- ArrayDeque:基于数组的双端队列
- 队列操作:offer(), poll(), peek()等
Map接口
- Map接口基本方法:put(), get(), remove(), containsKey(), keySet(), values(), entrySet()等
- HashMap:基于哈希表的实现
- 内部结构:数组+链表+红黑树(Java 8+)
- 负载因子和初始容量
- 哈希冲突处理
- LinkedHashMap:保持插入顺序的HashMap
- TreeMap:基于红黑树的有序映射
- Hashtable:线程安全的哈希表(较少使用)
- EnumMap:专为枚举键优化的Map
- IdentityHashMap:使用==而非equals()的特殊Map
- WeakHashMap:带有弱引用键的Map
- 各实现类的选择标准和性能特征
迭代器
- Iterator接口:hasNext(), next(), remove()
- ListIterator:双向迭代
- fail-fast机制:并发修改异常(ConcurrentModificationException)
- 迭代过程中安全修改集合
- foreach循环与迭代器的关系
- Iterable接口与可迭代集合
- Spliterator:可分割迭代器(Java 8+)
泛型的使用
- 带泛型的集合声明和使用
- 类型安全和避免类型转换
- 泛型通配符在集合中的应用
- 泛型嵌套:List<Map<String, Integer>>等
- 原始类型(raw type)和向后兼容性
- 泛型与数组的区别
集合工具类
- Collections工具类
- 排序:sort(), reverseOrder()
- 搜索:binarySearch()
- 极值:max(), min()
- 填充和替换:fill(), replaceAll()
- 同步包装:synchronizedXxx()
- 不可修改包装:unmodifiableXxx()
- 单例集合:singletonXxx()
- 其他实用方法:disjoint(), frequency()等
- Arrays工具类
- 转换:asList()
- 排序和搜索:sort(), binarySearch()
- 填充和复制:fill(), copyOf(), copyOfRange()
- 数组与集合的互操作
7. 泛型编程
泛型类与接口
- 泛型类的定义:class Name
- 泛型接口的定义:interface Name
- 类型参数命名约定:E(元素), T(类型), K(键), V(值)等
- 多类型参数:<K, V>
- 泛型类的实例化和使用
- 类型参数的限定:
- 泛型类的继承和子类型
- 泛型和构造器
泛型方法
- 泛型方法的定义:
T methodName(T param) - 类型推断机制
- 静态泛型方法
- 泛型方法vs泛型类
- 类型参数的作用域
- 可变参数与泛型的结合
- 通用工具方法的设计
类型擦除
- 泛型的实现原理
- 类型擦除的概念和过程
- 泛型在运行时的实际类型
- 泛型的限制:类型参数不能是基本类型,不能创建泛型数组,不能用instanceof等
- 桥接方法(bridge method)
- 泛型的向前兼容性
- 类型擦除带来的问题及解决方案
泛型通配符
- 无界通配符:<?>
- 上界通配符:<? extends T>
- 读取安全,写入受限
- Producer Extends原则
- 下界通配符:<? super T>
- 写入安全,读取受限
- Consumer Super原则
- PECS原则(Producer-Extends, Consumer-Super)
- 通配符捕获
- 通配符vs类型参数
- 复杂泛型结构的理解和应用
8. 输入输出流
File类
- 文件和目录表示
- 文件信息获取:exists(), isFile(), isDirectory(), length(), lastModified()等
- 文件操作:createNewFile(), delete(), renameTo()
- 目录操作:mkdir(), mkdirs(), list(), listFiles()
- 文件路径处理:绝对路径、相对路径
- 临时文件创建
- File对象的局限性和新I/O API(NIO.2)的改进
字节流
- InputStream抽象类及其方法:read(), available(), close()等
- OutputStream抽象类及其方法:write(), flush(), close()等
- 文件字节流:FileInputStream, FileOutputStream
- 内存字节流:ByteArrayInputStream, ByteArrayOutputStream
- 数据处理流:DataInputStream, DataOutputStream
- 对象流:ObjectInputStream, ObjectOutputStream
- 缓冲字节流:BufferedInputStream, BufferedOutputStream
- 打印流:PrintStream
- 流的链接和包装模式
字符流
- Reader抽象类及其方法:read(), ready(), close()等
- Writer抽象类及其方法:write(), append(), flush(), close()等
- 文件字符流:FileReader, FileWriter
- 内存字符流:CharArrayReader, CharArrayWriter, StringReader, StringWriter
- 缓冲字符流:BufferedReader, BufferedWriter
- 打印字符流:PrintWriter
- 桥接流:InputStreamReader, OutputStreamWriter
- 字符编码与解码
缓冲流
- 缓冲流的工作原理
- 缓冲区大小设置和性能影响
- 缓冲区刷新操作
- 行读取:BufferedReader.readLine()
- 缓冲流的效率提升
- 何时使用缓冲流
- 缓冲流的常见用法和模式
序列化
- 对象序列化的概念和目的
- Serializable接口:标记接口
- 序列化过程和反序列化过程
- serialVersionUID的作用和指定
- 定制序列化:writeObject()和readObject()方法
- transient关键字:排除不需要序列化的字段
- 序列化的安全性考虑
- 序列化的替代方案:JSON、XML等
- 实战:深拷贝、对象持久化和网络传输
9. 多线程编程
线程基础
- 进程vs线程
- 线程的创建方式:
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口(带返回值)
- 使用线程池
- 线程的生命周期:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
- 线程控制:start(), run(), sleep(), join(), yield(), interrupt()
- 线程优先级和调度
- 守护线程vs用户线程
- 线程组(ThreadGroup)
线程同步
- 线程安全问题:竞态条件和数据不一致
- synchronized关键字
- 同步方法
- 同步代码块
- 对象锁vs类锁
- 内置锁和监视器(Monitor)
- volatile关键字
- 可见性保证
- 有序性保证
- 不保证原子性
- 双重检查锁定(Double-Checked Locking)
- 线程安全的单例模式
- 不可变对象和线程安全
- 同步的性能开销和优化
锁机制
- Lock接口和ReentrantLock
- 与synchronized的区别
- 公平锁vs非公平锁
- 可中断锁
- 锁超时
- 条件变量(Condition)
- 读写锁:ReadWriteLock和ReentrantReadWriteLock
- 读共享写互斥
- 写锁降级
- StampedLock(Java 8+):乐观读锁
- 死锁问题
- 死锁条件
- 死锁预防和检测
- 死锁避免
- 活锁和饥饿问题
- 锁优化:粗锁和细锁、锁分离、锁消除
线程通信
- wait/notify机制
- Object.wait():释放锁等待通知
- Object.notify()/notifyAll():发送通知
- 生产者-消费者模式
- Condition接口
- await()和signal()/signalAll()
- 多条件变量
- 阻塞队列
- BlockingQueue接口及实现
- 生产者-消费者模式的改进
- 信号量(Semaphore)
- 栅栏(CyclicBarrier)和闭锁(CountDownLatch)
- 交换器(Exchanger)
- 阻塞vs轮询vs回调
线程池
- Executor框架
- Executor接口:执行任务
- ExecutorService接口:管理服务
- Executors工厂方法
- 常用线程池
- FixedThreadPool:固定大小
- CachedThreadPool:缓存复用
- SingleThreadExecutor:单线程
- ScheduledThreadPool:定时执行
- ThreadPoolExecutor
- 核心线程数和最大线程数
- 任务队列
- 拒绝策略
- 线程工厂
- 生命周期管理
- ForkJoinPool(Java 7+):工作窃取算法
- 定时任务调度
- 线程池使用最佳实践
并发工具类
- CountDownLatch:等待多个线程完成
- CyclicBarrier:线程相互等待到达屏障点
- Semaphore:控制并发访问的数量
- Phaser:更灵活的多阶段同步器
- Exchanger:两线程交换数据
- CompletableFuture(Java 8+):异步编程
- 原子变量类:AtomicInteger, AtomicLong等
- 并发集合:
- ConcurrentHashMap
- CopyOnWriteArrayList
- ConcurrentLinkedQueue
- BlockingQueue实现类
- 线程安全实现的选择和性能考量
10. Java 8+新特性
Lambda表达式
- Lambda表达式语法:() -> {}
- 函数式接口:仅有一个抽象方法的接口
- 内置函数式接口:
- Consumer
:消费型 - Supplier
:供给型 - Function<T, R>:函数型
- Predicate
:断言型 - 其他函数式接口
- Consumer
- 方法引用:类::方法
- 静态方法引用:ClassName::staticMethod
- 实例方法引用:instance::method
- 类方法引用:ClassName::method
- 构造方法引用:ClassName::new
- 变量捕获和作用域规则
- Lambda表达式的类型推断
- 闭包和闭包陷阱
Stream API
- 流的概念和特点:不存储数据、函数式操作、延迟执行、可能一次性
- 流的创建:collection.stream(), Stream.of(), Arrays.stream()等
- 中间操作:
- 筛选和切片:filter(), distinct(), limit(), skip()
- 映射:map(), flatMap()
- 排序:sorted()
- 查看:peek()
- 终端操作:
- 匹配和查找:allMatch(), anyMatch(), noneMatch(), findFirst(), findAny()
- 归约:reduce()
- 收集:collect(), Collectors工具类
- 迭代:forEach()
- 计数:count()
- 并行流:parallelStream()
- 数值流:IntStream, LongStream, DoubleStream
- 流操作的最佳实践和性能考量
Optional类
- Optional
类的目的和用法 - 创建Optional对象:Optional.of(), Optional.ofNullable(), Optional.empty()
- 检查值:isPresent(), isEmpty()(Java 11+)
- 获取值:get(), orElse(), orElseGet(), orElseThrow()
- 条件操作:filter(), map(), flatMap()
- 消费值:ifPresent(), ifPresentOrElse()(Java 9+)
- 组合多个Optional
- 作为返回类型使用Optional
- Optional最佳实践
新日期时间API
- 不可变性和线程安全
- 本地日期时间:
- LocalDate:年、月、日
- LocalTime:时、分、秒、纳秒
- LocalDateTime:组合日期和时间
- 时区相关:
- ZoneId:时区标识
- ZoneOffset:UTC偏移量
- ZonedDateTime:带时区的日期时间
- 时间间隔:
- Duration:基于时间的间隔
- Period:基于日期的间隔
- ChronoUnit:时间单位
- 格式化和解析:
- DateTimeFormatter:日期时间格式化
- 预定义格式和自定义模式
- 时间调整器:
- TemporalAdjusters:日期调整器
- 常用调整器:firstDayOfMonth(), lastDayOfYear()等
- 新旧API的转换
默认方法
- 接口中的默认方法(default methods)
- 默认方法的语法和使用
- 多接口继承时的冲突解决
- 默认方法与抽象类的比较
- 静态接口方法
- API演化和向后兼容性
- 默认方法最佳实践
11. 反射与注解
反射机制
- 反射概念和用途
- 动态获取类信息
- 动态实例化对象
- 动态访问和修改字段
- 动态调用方法
- 反射访问私有成员
- 反射性能开销和优化
- 反射的应用场景和限制
Class类
- 获取Class对象的方式:
- 对象.getClass()
- 类名.class
- Class.forName()
- 类信息查询:
- 名称和修饰符:getName(), getModifiers()等
- 父类和接口:getSuperclass(), getInterfaces()
- 构造器:getConstructors(), getDeclaredConstructors()
- 方法:getMethods(), getDeclaredMethods()
- 字段:getFields(), getDeclaredFields()
- 成员信息:Constructor, Method, Field类
- 调用与访问:invoke(), get(), set()等
- 泛型信息:Type, ParameterizedType等
- 反射与数组
动态代理
- 代理模式基础
- JDK动态代理:
- InvocationHandler接口
- Proxy类和newProxyInstance()方法
- 代理对象的创建和使用
- CGLIB动态代理:
- 基于继承的代理
- 增强器和回调
- 动态代理的应用场景:
- AOP(面向切面编程)
- RPC(远程过程调用)
- ORM(对象关系映射)
- 代理性能比较和选择
注解基础
- 注解的概念和用途
- 内置注解:
- @Override:重写方法检查
- @Deprecated:标记过时项
- @SuppressWarnings:抑制警告
- @SafeVarargs:可变参数类型安全
- @FunctionalInterface:函数式接口标记
- 元注解:
- @Retention:保留策略
- @Target:适用目标
- @Documented:文档包含
- @Inherited:注解继承
- @Repeatable:可重复注解(Java 8+)
- 自定义注解:
- 定义语法
- 注解元素类型
- 默认值
- 使用限制
- 注解处理器:
- 运行时处理:反射API
- 编译时处理:注解处理器API
- 注解最佳实践
12. 单元测试
JUnit使用
- JUnit框架概述(JUnit 4/5)
- 测试类和测试方法
- 基本注解:
- @Test:标记测试方法
- @Before/@BeforeEach:测试前准备
- @After/@AfterEach:测试后清理
- @BeforeClass/@BeforeAll:类初始化
- @AfterClass/@AfterAll:类销毁
- @Ignore/@Disabled:跳过测试
- 测试生命周期
- 参数化测试
- 测试套件
- 超时测试
- 异常测试
- 测试执行顺序
断言
- JUnit断言方法:
- assertEquals():相等性断言
- assertTrue()/assertFalse():布尔断言
- assertNull()/assertNotNull():空值断言
- assertSame()/assertNotSame():引用相等断言
- assertThrows():异常断言
- assertAll():组合断言(JUnit 5)
- Hamcrest匹配器:更具表达力的断言
- AssertJ:流式断言API
- 自定义断言方法
- 断言消息和失败处理
- 软断言:收集多个失败
- 断言最佳实践
测试覆盖率
- 覆盖率类型:
- 行覆盖率(Line Coverage)
- 分支覆盖率(Branch Coverage)
- 路径覆盖率(Path Coverage)
- 方法覆盖率(Method Coverage)
- 类覆盖率(Class Coverage)
- 覆盖率工具:
- JaCoCo
- Cobertura
- EclEmma
- 覆盖率报告解读
- 覆盖率目标设定
- 测试质量和覆盖率的关系
- 提高测试覆盖率的策略
- 覆盖率和测试驱动开发(TDD)
相关文章
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 AnA.!
评论