Featured image of post Java核心技术卷1知识点

Java核心技术卷1知识点

主要为Java核心技术卷1的知识点,主要为基础知识

第1章 Java程序设计概述

Java语言的特点

  • 平台无关性:一次编写,到处运行(Write Once, Run Anywhere),通过JVM实现
  • 面向对象:支持封装、继承、多态三大特性
  • 安全性:强类型检查、自动内存管理(垃圾回收)、字节码验证
  • 健壮性:异常处理机制、自动内存管理
  • 多线程:内置对并发编程的支持

Java体系结构

  • Java虚拟机(JVM):执行字节码的虚拟计算机,实现平台无关性
  • Java运行时环境(JRE):包括JVM和核心类库
  • Java开发工具包(JDK):包括JRE和开发工具(编译器、调试器等)

第2章 Java程序设计环境

第一个Java程序

1
2
3
4
5
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
  • 编译javac HelloWorld.java,生成HelloWorld.class字节码文件
  • 运行java HelloWorld

Java程序结构

  • 源文件命名:必须与公共类名相同,以.java结尾
  • 类定义:使用class关键字,可包含属性和方法
  • 主方法public static void main(String[] args),程序入口点

第3章 Java的基本程序设计结构

数据类型

1. 基本数据类型(8种)

类型 大小 范围 默认值
整数类型
byte 1字节 -128 ~ 127 0
short 2字节 -32768 ~ 32767 0
int 4字节 -2147483648 ~ 2147483647 0
long 8字节 很大 0L
浮点类型
float 4字节 约±3.4×10^38 0.0f
double 8字节 约±1.8×10^308 0.0
字符类型
char 2字节 0 ~ 65535(Unicode) ‘\u0000’
布尔类型
boolean 1位 true/false false

注:Java是强类型语言,变量必须声明类型后才能使用

2. 引用数据类型

  • 类、接口、数组、字符串等
  • 默认值为null

变量与常量

  • 变量声明type identifier [=value];

    1
    2
    
    int age = 25;
    double salary = 5000.0;
    
  • 常量:使用final关键字修饰,必须初始化且值不可变

    1
    
    final double PI = 3.1415926;
    
  • 类常量:使用static final修饰,属于类而非对象

    1
    
    public static final int MAX_SIZE = 100;
    

运算符与表达式

1. 算术运算符

  • +-*/%(取余)
  • ++(自增)、--(自减)可前置或后置

2. 关系运算符

  • ><>=<===!=,结果为boolean类型

3. 逻辑运算符

  • &&(逻辑与)、||(逻辑或)、!(逻辑非)
  • 具有短路特性:(a && b)中,若afalse,则b不会计算

4. 位运算符

  • &(按位与)、|(按位或)、^(按位异或)、~(按位取反)
  • <<(左移)、>>(右移)、>>>(无符号右移)

5. 赋值运算符

  • =+=-=*=/=%=

6. 字符串连接

  • 使用+运算符连接字符串和其他类型,会自动转换为字符串

    1
    2
    3
    
    String name = "Alice";
    int age = 30;
    System.out.println("Name: " + name + ", Age: " + age); // Name: Alice, Age: 30
    

流程控制结构

1. 条件语句

  • if-else

    1
    2
    3
    4
    5
    
    if (condition) {
        // 条件为true时执行
    } else {
        // 条件为false时执行
    }
    
  • 多重条件

    1
    2
    3
    4
    5
    6
    7
    
    if (condition1) {
        // ...
    } else if (condition2) {
        // ...
    } else {
        // ...
    }
    
  • switch-case:支持byteshortintcharStringenum类型

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    switch (expression) {
        case value1:
            // 执行代码
            break;
        case value2:
            // 执行代码
            break;
        default:
            // 所有case都不匹配时执行
    }
    

2. 循环语句

  • for循环

    1
    2
    3
    
    for (initialization; condition; update) {
        // 循环体
    }
    

    增强for循环(用于遍历集合或数组)

    1
    2
    3
    
    for (type element : collection/array) {
        // 操作element
    }
    
  • while循环

    1
    2
    3
    
    while (condition) {
        // 循环体
    }
    
  • do-while循环

    1
    2
    3
    
    do {
        // 循环体
    } while (condition);
    

数组

1. 数组声明与初始化

1
2
3
4
5
6
7
8
// 静态初始化
int[] numbers = {1, 2, 3, 4, 5};

// 动态初始化
String[] names = new String[5]; // 长度为5的String数组,元素默认null

// 多维数组
int[][] matrix = new int[3][4]; // 3行4列的二维数组

2. 数组特性

  • 长度固定,一旦创建不可改变
  • 元素类型必须一致
  • 通过索引访问(从0开始)
  • 数组对象有length属性获取长度

3. 数组操作

  • 遍历数组:

    1
    2
    3
    
    for (int i = 0; i < numbers.length; i++) {
        System.out.println(numbers[i]);
    }
    

    或使用增强for循环

    1
    2
    3
    
    for (int num : numbers) {
        System.out.println(num);
    }
    

第4章 对象与类

面向对象编程基础

1. 类与对象

  • :对象的模板,定义属性和方法
  • 对象:类的实例,通过new关键字创建

2. 面向对象三大特性

  • 封装:将数据和操作封装在类中,通过访问控制限制外部直接访问
  • 继承:子类继承父类的属性和方法,实现代码重用
  • 多态:同一方法在不同对象上表现出不同行为

类的定义与使用

1. 类定义语法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[访问修饰符] class 类名 [extends 父类] [implements 接口列表] {
    // 成员变量(属性)
    [修饰符] 数据类型 变量名;
    
    // 构造方法
    类名([参数列表]) {
        // 初始化代码
    }
    
    // 成员方法
    [修饰符] 返回类型 方法名([参数列表]) {
        // 方法体
    }
}

2. 成员变量

  • 实例变量:属于对象,每个对象独立拥有
  • 静态变量(类变量):使用static修饰,属于类,所有对象共享

3. 方法

  • 实例方法:可访问实例变量和静态变量
  • 静态方法:使用static修饰,只能访问静态变量,通过类名直接调用

4. 对象创建与使用

1
2
3
4
5
6
// 创建对象
ClassName objectName = new ClassName();

// 使用对象
objectName.methodName();
objectName.variableName = value;

访问控制

Java提供四种访问控制级别,按可见范围从大到小排列:

修饰符 类内部 同包 子类(不同包) 其他包
public
protected
默认(无修饰符)
private

注:类只能使用public或默认修饰符

构造方法

  • 特点
    • 方法名与类名相同
    • 无返回类型(连void也没有)
    • 用于对象初始化

1. 默认构造方法

  • 若类没有显式定义任何构造方法,编译器会自动生成一个无参构造方法
  • 若已定义任何构造方法,则不会自动生成

2. 构造方法重载

  • 多个构造方法,参数列表不同(参数个数、类型或顺序不同)
  • 调用时根据实参类型和数量匹配相应构造方法

3. 构造方法调用

  • 使用this([参数])调用同一个类的其他构造方法
  • 必须位于构造方法的第一行

方法详解

1. 方法参数传递

  • 基本类型参数:传递值的副本,方法内修改不影响原始值
  • 引用类型参数:传递引用的副本(指向同一对象),方法内可修改对象状态,但不能改变引用本身

2. 方法重载

  • 同一类中,方法名相同但参数列表不同(参数个数、类型或顺序不同)
  • 返回类型不作为重载判断条件

3. 可变参数(Varargs)

  • 方法参数列表中最后一个参数可以是可变参数,使用...表示

  • 本质是一个数组

    1
    2
    3
    4
    5
    
    public void printNumbers(int... numbers) {
        for (int num : numbers) {
            System.out.println(num);
        }
    }
    

    调用printNumbers(1, 2, 3);printNumbers(new int[]{4, 5, 6});

对象构造过程

  1. 分配内存空间
  2. 成员变量默认初始化(基本类型为默认值,引用类型为null
  3. 执行实例初始化块(按定义顺序执行)
  4. 执行构造方法

类之间的关系

1. 依赖(“uses-a"关系)

  • 一个类的方法使用另一个类的对象作为参数或局部变量
  • 例:public void processOrder(Customer customer)

2. 聚合(“has-a"关系)

  • 一个类包含另一个类的对象作为成员变量
  • 例:private Address address;

3. 继承(“is-a"关系)

  • 一个类继承另一个类的属性和方法
  • 例:public class Manager extends Employee

  • 作用:组织类、避免命名冲突、控制访问权限

  • 定义:源文件首行非注释语句package packageName;

  • 命名规则:建议使用域名逆序(如com.example.project

  • 访问控制:同包类可互相访问,不同包只能访问public

  • 导入类

    1
    2
    
    import packageName.ClassName; // 导入单个类
    import packageName.*; // 导入整个包(不包含子包)
    
  • 静态导入:导入静态成员

    1
    2
    
    import static java.lang.Math.PI;
    import static java.util.Arrays.sort;
    

文档注释

  • 使用/** ... */格式,用于生成API文档
  • 主要标签:
    • @author:作者
    • @version:版本
    • @param:参数说明
    • @return:返回值说明
    • @throws:异常说明
  • 通过javadoc命令生成HTML文档

类设计技巧

  1. 数据私有:所有字段设为private,提供公共访问方法
  2. 对数据初始化:确保所有字段在使用前被初始化
  3. 避免过多基本类型:考虑用类替代相关基本类型组合
  4. 慎用访问器/更改器:不必要的字段不提供专门访问方法
  5. 分解职责过重的类:单一职责原则(SRP)
  6. 命名清晰:类名名词,方法名动词短语
  7. 优先使用不可变类:如String,提高线程安全性

第1-4章复习重点

  1. Java基础:平台无关性原理、JVM/JRE/JDK区别
  2. 数据类型:8种基本类型的范围和默认值、引用类型特点
  3. 流程控制:各种循环和条件语句的使用场景
  4. 数组:声明、初始化、遍历方法
  5. 面向对象基础:类与对象关系、封装特性、访问控制
  6. 构造方法:重载、this关键字使用、初始化顺序
  7. 方法:参数传递机制、重载原理、可变参数用法

提示:重点练习类的设计,包括成员变量、构造方法和方法的编写,以及对象的创建与使用

第5章 继承

类、超类和子类

  • 继承定义:子类通过extends关键字继承父类

    1
    
    public class Manager extends Employee { ... }
    
  • 子类特性

    • 继承父类非私有成员(字段和方法)
    • 可添加新成员
    • 可覆盖(override)父类方法
  • 构造方法:子类构造方法必须先调用父类构造方法(super()),且必须位于首行

  • 方法覆盖

    1
    2
    
    @Override // 显式标记覆盖,编译时检查
    public double getSalary() { ... }
    
  • 强制类型转换

    1
    2
    
    Manager m = (Manager) employee; // 向下转型需显式转换
    if (employee instanceof Manager) { ... } // 使用instanceof检查类型
    

多态

  • 定义:父类引用可以指向子类对象,调用方法时执行实际对象(子类)的方法
  • “is-a"原则:子类对象可视为父类对象(如"Manager is an Employee”)
  • 动态绑定:运行时根据实际对象类型确定调用的方法
  • 编译与运行时
    • 编译时:检查引用类型是否具有该方法
    • 运行时:执行实际对象的方法

final关键字

  • 修饰类:类不可被继承(如String类)
  • 修饰方法:方法不可被覆盖
  • 修饰变量:变量变为常量,只能赋值一次

Object:所有类的超类

  • 默认继承:所有类(除Object本身)都直接或间接继承Object
  • 常用方法
    • equals(Object):比较对象是否相等(默认比较引用)
    • hashCode():返回对象哈希码(配合equals使用)
    • toString():返回对象字符串表示(建议重写)
    • getClass():返回对象的Class对象(运行时类型信息)

抽象类

  • 定义:包含抽象方法(无实现)的类,必须声明为abstract

    1
    2
    3
    
    public abstract class Shape {
        public abstract double area(); // 抽象方法
    }
    
  • 特点

    • 不能实例化(不能用new创建对象)
    • 子类必须实现所有抽象方法(除非子类也是抽象类)
    • 可包含具体方法和字段

第6章 接口与内部类

接口

  • 定义

    1
    2
    3
    
    public interface Comparable {
        int compareTo(Object o); // 接口方法默认public abstract
    }
    
  • 特性

    • 所有方法默认public abstract
    • 所有字段默认public static final
    • 不能实例化,只能被类实现
    • 类通过implements实现接口
    • 一个类可实现多个接口(解决Java单继承限制)

默认方法

  • 接口中可提供方法的默认实现,用default修饰

    1
    2
    3
    
    public interface Collection {
        default void forEach(Consumer action) { ... }
    }
    
  • 冲突解决规则

    1. 类优先原则:类中方法优先于接口默认方法
    2. 接口冲突:一个类实现两个接口,且都有相同默认方法,必须在类中重写该方法

lambda表达式

  • 定义:简洁表示函数式接口(只有一个抽象方法的接口)的实例

  • 基本语法

    1
    
    (参数列表) -> { 方法体 }
    
  • 简化规则

    • 参数类型可省略(类型推断)
    • 单参数时可省略括号
    • 方法体只有一条语句可省略花括号和return
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    // 传统方式
    Comparator<String> comp = new Comparator<String>() {
        public int compare(String s1, String s2) {
            return s1.length() - s2.length();
        }
    };
    
    // lambda方式
    Comparator<String> comp = (s1, s2) -> s1.length() - s2.length();
    

方法引用

  • 定义:直接引用已有方法作为lambda表达式

  • 四种形式

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    // 对象::实例方法
    obj::methodName
    
    // 类::静态方法
    ClassName::staticMethodName
    
    // 类::实例方法(第一个参数作为调用者)
    ClassName::instanceMethodName
    
    // 数组::构造方法
    int[]::new
    

内部类

  • 定义:在另一个类内部定义的类
  • 类型
    1. 成员内部类:在类内但方法外定义,可直接访问外部类所有成员
    2. 静态内部类:用static修饰,只能访问外部类静态成员
    3. 局部内部类:在方法内定义,作用域仅限于该方法
    4. 匿名内部类:没有名字的内部类,用于创建一次性对象

第7章 异常处理

异常分类

  • Throwable:所有错误和异常的根类
    • Error:系统内部错误(如StackOverflowError),应用程序不应捕获
    • Exception:程序运行时错误,可分为:
      • 运行时异常(RuntimeException):非检查异常(如NullPointerException
      • 检查型异常(Checked Exception):必须显式处理(捕获或声明抛出)

异常处理机制

  • 抛出异常

    1
    2
    3
    
    if (value < 0) {
        throw new IllegalArgumentException("Negative value not allowed");
    }
    
  • 捕获异常

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    try {
        // 可能抛出异常的代码
    } catch (ExceptionType1 e) {
        // 处理ExceptionType1异常
    } catch (ExceptionType2 e) {
        // 处理ExceptionType2异常
    } finally {
        // 无论是否发生异常都执行的代码(如资源清理)
    }
    
  • 多重捕获(Java 7+):

    1
    
    catch (IOException | SQLException e) { ... } // 捕获多种异常
    

try-with-resources语句

  • 自动关闭资源:适用于实现AutoCloseable接口的资源(如文件流、数据库连接)

    1
    2
    3
    
    try (FileInputStream fis = new FileInputStream("file.txt")) {
        // 使用资源
    } // 自动调用fis.close(),即使发生异常
    
  • 多个资源

    1
    
    try (ResourceA ra = new ResourceA(); ResourceB rb = new ResourceB()) { ... }
    

自定义异常

  • 继承Exception(检查型异常)或RuntimeException(非检查型异常)

  • 建议提供两个构造方法:

    1
    2
    3
    4
    
    public class MyException extends Exception {
        public MyException() { super(); }
        public MyException(String message) { super(message); }
    }
    

异常使用最佳实践

  1. 只在异常情况下使用异常:异常处理比条件判断慢得多

  2. 异常链:捕获异常后包装成更高层异常,保留原始异常信息

    1
    2
    3
    
    try { ... } catch (SQLException e) {
        throw new ServiceException("Database error", e); // 异常链
    }
    
  3. 不要捕获Throwable:应捕获具体异常,避免隐藏系统错误

  4. 优先传递异常:若当前层无法处理,应将异常向上抛出

  5. finally慎用return:可能覆盖try块中的return值

第8章 泛型程序设计

为什么使用泛型

  • 类型安全:编译时检查类型,避免运行时ClassCastException

  • 代码重用:一个类/方法可用于多种类型

  • 消除强制类型转换

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    // 非泛型
    List list = new ArrayList();
    list.add("Hello");
    String s = (String) list.get(0); // 需要强制转换
    
    // 泛型
    List<String> list = new ArrayList<>();
    list.add("Hello");
    String s = list.get(0); // 无需强制转换
    

定义泛型类

  • 语法

    1
    2
    3
    4
    5
    
    public class Box<T> {
        private T value;
        public T getValue() { return value; }
        public void setValue(T value) { this.value = value; }
    }
    
  • 使用

    1
    2
    
    Box<Integer> intBox = new Box<>();
    intBox.setValue(10);
    

泛型方法

  • 可在普通类中定义泛型方法

    1
    2
    3
    4
    5
    
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }
    
  • 调用:

    1
    2
    
    Integer[] intArray = {1, 2, 3};
    printArray(intArray); // 自动推断T为Integer
    

类型变量的限定

  • 限制类型变量必须是某个类的子类或实现某个接口

    1
    
    public <T extends Comparable> void sort(T[] array) { ... } // T必须实现Comparable接口
    

泛型代码和虚拟机

  • 类型擦除:泛型信息只在编译期存在,运行时被擦除
    • 泛型类Box<T>编译后变为原始类Box
    • 类型变量被替换为上限(若无上限则为Object
  • 桥接方法:为保持多态性,编译器生成的特殊方法
  • 泛型数组:不能直接创建泛型数组(new T[]),但可通过强制类型转换实现

泛型的限制与局限性

  1. 不能实例化类型变量new T()不合法
  2. 不能创建泛型数组T[] array = new T[10];不合法
  3. 静态上下文中类型变量无效:静态方法/字段不能使用类的类型变量
  4. 不能捕获或抛出泛型类的实例catch (T e)不合法
  5. 不能使用基本类型实例化泛型:需使用包装类(如Integer代替int

通配符(Wildcards)

  • 上界通配符<? extends Type>表示可以接受该类型或其子类型

    1
    
    public void printList(List<? extends Number> list) { ... } // 接受任何Number子类的列表
    
  • 下界通配符<? super Type>表示可以接受该类型或其父类型

    1
    
    public void addNumbers(List<? super Integer> list) { ... } // 接受Integer或其父类的列表
    
  • 无界通配符<?>等同于<? extends Object>

    1
    
    public void printObjectList(List<?> list) { ... } // 接受任何类型的列表
    

泛型最佳实践

  1. 使用泛型集合:如List<String>而非原始List
  2. 定义泛型方法而非泛型类:若通用性仅限于少数方法
  3. 合理使用通配符:提高API灵活性
  4. 必要时使用类型检查和强制转换:在泛型信息丢失时
  5. 考虑类型安全的容器:如Collections.checkedList()

第4-8章复习重点

  1. 面向对象核心:封装、继承、多态的实现与应用场景
  2. 继承机制
    • 子类与父类关系及构造顺序
    • 方法覆盖与super关键字
    • final关键字的使用
  3. 接口与lambda
    • 接口特性与默认方法
    • lambda表达式简化函数式接口实现
  4. 异常处理
    • 检查型与非检查型异常区别
    • try-catch-finally与try-with-resources用法
    • 自定义异常最佳实践
  5. 泛型
    • 类型擦除机制
    • 通配符使用(上界、下界)
    • 泛型类与方法设计

提示:重点练习类的继承关系设计、接口实现、异常处理策略和泛型集合使用,这些是Java开发的核心技能。

第9章 集合

Java集合框架概述

  • 集合特点

    • 大小可变,可存储对象引用(基本类型自动装箱)
    • 支持泛型,类型安全
    • 主要接口:Collection(单元素集合)和Map(键值对集合)
  • 接口与实现分离

    • 面向接口编程,实现类可互换(如List可用ArrayListLinkedList
    • 提高代码灵活性和可维护性

Collection接口体系

根接口Collection<E>

  • 核心方法:add(E e)iterator()size()contains(Object o)
  • 子接口:
    • List<E>:有序、可重复,支持索引访问
      • 实现:ArrayList(动态数组,随机访问快)、LinkedList(双向链表,增删快)
    • Set<E>:无序、唯一
      • 实现:HashSet(哈希表,性能好)、TreeSet(有序,基于红黑树)、LinkedHashSet(插入顺序)
    • Queue<E>:FIFO(先进先出)
      • 实现:LinkedList(也实现Deque)、PriorityQueue(优先级队列)

迭代器

  • 功能:遍历集合元素,支持删除操作

  • 核心方法

    1
    2
    3
    
    boolean hasNext(); // 是否有下一个元素
    E next(); // 返回下一个元素
    void remove(); // 删除当前元素(可选操作)
    
  • 增强for循环:内部使用迭代器,简化遍历

    1
    
    for (E element : collection) { ... }
    
  • 注意:遍历时直接修改集合结构会抛出ConcurrentModificationException,应使用迭代器的remove()方法

Map接口

  • 特点:存储key-value对,key唯一

  • 核心实现

    • HashMap:基于哈希表,性能最佳,无序
    • TreeMap:按键排序(自然顺序或定制比较器)
    • LinkedHashMap:保持插入顺序,可实现LRU缓存
    • Hashtable:线程安全(同步),已过时,推荐使用ConcurrentHashMap
  • 视图操作

    1
    2
    3
    
    Set<K> keySet(); // 获取所有key的集合
    Collection<V> values(); // 获取所有value的集合
    Set<Map.Entry<K, V>> entrySet(); // 获取所有键值对
    

集合工具类

  • Collections:提供静态方法操作集合

    • 排序:sort(List<T> list)(自然顺序)、sort(List<T> list, Comparator<? super T> c)(定制顺序)
    • 查找:binarySearch()max()min()
    • 包装:synchronizedList()(线程安全)、unmodifiableList()(只读)
    • 填充:fill(List<T> list, T obj)
    • 洗牌:shuffle(List<?> list)
  • Arrays:数组与集合互转

    1
    2
    3
    4
    5
    
    // 数组转集合(固定大小,不支持增删)
    List<String> list = Arrays.asList("a", "b", "c");
    
    // 集合转数组
    String[] array = list.toArray(new String[0]);
    

特殊集合

  • WeakHashMap:键使用弱引用,当键不再被其他对象强引用时,可被垃圾回收,适用于缓存场景
  • PriorityQueue:优先队列,元素按自然顺序或定制比较器排序,poll()返回最小元素
  • EnumSet:专为枚举类型设计的高效Set实现
  • LinkedHashSet:保持插入顺序的HashSet,遍历时按插入顺序访问

第10章 GUI程序设计

Java GUI工具包简史

  • AWT(Abstract Window Toolkit)

    • Java最早的GUI工具包(1995年)
    • 依赖操作系统原生组件(重量级组件)
    • 组件外观受系统影响,功能有限,现已被Swing和JavaFX替代
  • Swing

    • 完全用Java实现(轻量级组件)
    • 跨平台一致外观
    • 提供更丰富组件(如表格、树等)
    • 包名:javax.swing,是Java SE标准库一部分

基本GUI构建

1. 窗口(JFrame)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import javax.swing.*;
public class MyFrame extends JFrame {
    public MyFrame() {
        setTitle("My Window");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序
        setLocationRelativeTo(null); // 窗口居中
        // 添加组件
        JLabel label = new JLabel("Hello, Swing!");
        add(label);
        setVisible(true); // 必须设置为true才显示
    }
}

2. 容器(Container)

  • 组件不能独立显示,必须添加到容器中
  • 常用容器:
    • JFrame:主窗口
    • JPanel:轻量级面板,用于组织和嵌套组件
    • JScrollPane:带滚动条的容器,用于显示大内容
    • JOptionPane:对话框容器,用于显示消息和获取用户输入

布局管理器

  • 控制容器中组件的排列方式,Swing提供多种布局:
布局管理器 特点 适用场景
FlowLayout 按添加顺序排列,默认居中对齐 简单界面,组件较少
BorderLayout 分为东、西、南、北、中五个区域 主窗口布局,通常中心区域放置主要内容
GridLayout 网格布局,所有组件大小相同 整齐排列的按钮、标签等
GridBagLayout 灵活网格,可设置组件跨越多个单元格,自定义大小 复杂界面,组件大小不一
BoxLayout 水平或垂直排列,可设置间距 工具栏、垂直菜单等
  • 使用示例

    1
    2
    3
    4
    5
    6
    
    // 设置JFrame使用BorderLayout
    setLayout(new BorderLayout());
    
    // 向不同区域添加组件
    add(new JButton("Top"), BorderLayout.NORTH);
    add(new JButton("Bottom"), BorderLayout.SOUTH);
    

事件处理机制

1. 事件模型

  • 事件源:产生事件的组件(如按钮、文本框)
  • 事件:描述发生的事情(如点击、输入)
  • 事件监听器:接收并处理事件的对象,实现特定监听器接口

2. 常见事件类型

  • ActionListener:按钮点击、菜单选择等

    1
    2
    
    JButton button = new JButton("Click me");
    button.addActionListener(e -> System.out.println("Button clicked!"));
    
  • ItemListener:复选框、单选按钮状态变化

    1
    2
    
    JCheckBox checkBox = new JCheckBox("Remember me");
    checkBox.addItemListener(e -> System.out.println("Checkbox state: " + e.getStateChange()));
    
  • MouseListener:鼠标点击、进入、离开等

  • KeyListener:键盘按键事件

3. 适配器类

  • 为监听器接口提供默认实现,只需重写需要的方法

    1
    2
    3
    4
    5
    6
    7
    
    // 使用MouseAdapter简化鼠标事件处理
    button.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            System.out.println("Mouse clicked at: " + e.getX() + ", " + e.getY());
        }
    });
    

常用Swing组件

1. 标签(JLabel):显示文本或图像,不响应用户交互

1
2
JLabel label = new JLabel("Username:");
label.setToolTipText("This is a username label"); // 添加悬停提示

2. 按钮(JButton):可点击按钮

1
2
JButton button = new JButton("Submit");
button.setMnemonic(KeyEvent.VK_S); // 设置快捷键Alt+S

3. 文本组件

  • JTextField:单行文本输入
  • JPasswordField:密码输入(显示为星号)
  • JTextArea:多行文本区域(通常配合JScrollPane使用)

4. 选择组件

  • JCheckBox:复选框,可选中或取消选中
  • JRadioButton:单选按钮,需配合ButtonGroup使用(同一组内只能选一个)
  • JComboBox:下拉列表,可选择预定义选项

5. 对话框

  • JOptionPane:简单对话框,用于显示消息、获取用户输入

    1
    2
    3
    4
    5
    
    // 消息对话框
    JOptionPane.showMessageDialog(null, "Login successful!");
    
    // 确认对话框
    int option = JOptionPane.showConfirmDialog(null, "Do you want to save changes?");
    

第11章 Swing用户界面组件

Swing高级组件

1. 菜单(Menu)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 创建菜单栏
JMenuBar menuBar = new JMenuBar();

// 创建菜单
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F); // 设置Alt+F快捷键

// 添加菜单项
JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
openItem.addActionListener(e -> openFile());

// 添加到菜单和菜单栏
fileMenu.add(openItem);
menuBar.add(fileMenu);

// 将菜单栏设置到窗口
setJMenuBar(menuBar);

2. 工具栏(JToolBar)

1
2
3
JToolBar toolBar = new JToolBar();
toolBar.add(new JButton(new ImageIcon("open.png"))); // 添加带图标的按钮
add(toolBar, BorderLayout.NORTH);

3. 表格(JTable):显示和编辑二维数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 创建表格模型
Object[][] data = {{"Alice", 25}, {"Bob", 30}};
String[] columnNames = {"Name", "Age"};
DefaultTableModel model = new DefaultTableModel(data, columnNames);

// 创建表格
JTable table = new JTable(model);

// 添加滚动条
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);

4. 树(JTree):显示层次结构数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 创建树节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Child 1");
root.add(child1);

// 创建树
JTree tree = new JTree(root);

// 添加滚动条
add(new JScrollPane(tree));

布局管理进阶

1. GridBagLayout详解

  • 最灵活的布局管理器,支持组件跨越多个单元格

  • 通过GridBagConstraints设置组件位置、大小、对齐方式等

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    // 设置窗口使用GridBagLayout
    setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    
    // 添加组件到(0,0)位置,默认大小
    gbc.gridx = 0;
    gbc.gridy = 0;
    add(new JLabel("Username:"), gbc);
    
    // 添加组件到(1,0)位置,横向填充
    gbc.gridx = 1;
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.HORIZONTAL; // 水平方向填充
    add(new JTextField(20), gbc);
    

2. BoxLayout与Box组件

  • 垂直或水平排列组件,自动处理间距

    1
    2
    3
    4
    5
    6
    
    // 垂直排列组件
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.add(new JButton("Button 1"));
    panel.add(Box.createVerticalStrut(10)); // 添加垂直间距
    panel.add(new JButton("Button 2"));
    

Swing特性与最佳实践

1. 组件边框(Border)

1
2
3
4
5
6
// 创建带标题的边框
JLabel label = new JLabel("Content");
label.setBorder(BorderFactory.createTitledBorder("Title"));

// 创建空边框(用于间距)
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 上右下左间距

2. 图标(Icon)

  • 使用ImageIcon加载图片,支持多种格式(如PNG、JPG)

    1
    
    JButton button = new JButton(new ImageIcon("icon.png"));
    

3. 工具提示(ToolTip)

1
component.setToolTipText("This is a tooltip"); // 鼠标悬停显示提示

4. Swing应用程序结构最佳实践

  1. 在事件调度线程(Event Dispatch Thread, EDT)中创建和更新UI

    1
    
    SwingUtilities.invokeLater(() -> new MyFrame());
    
  2. 主窗口设置合适的关闭操作:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

  3. 合理使用布局管理器,避免绝对定位

  4. 使用面板(JPanel)组织相关组件,实现界面模块化

第12章 并发

线程基础

1. 线程与进程

  • 进程:独立执行的程序,拥有自己的内存空间
  • 线程:进程内的执行单元,共享进程内存,提高程序并发性

2. 创建线程的方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 方式1:继承Thread类
class MyThread extends Thread {
  @Override
  public void run() {
      System.out.println("Thread running");
  }
}
new MyThread().start(); // 启动线程

// 方式2:实现Runnable接口
Runnable task = () -> System.out.println("Runnable task running");
new Thread(task).start();

// 方式3:使用Callable和Future(有返回值)
Callable<Integer> task = () -> {
  // 执行任务
  return 42; // 返回结果
};
Future<Integer> future = Executors.newSingleThreadExecutor().submit(task);

3. 线程状态(6种):

1
Thread.State state = thread.getState(); // 获取线程状态
状态 描述
NEW 线程已创建但未启动(调用start()前)
RUNNABLE 线程可运行(正在执行或等待CPU时间片)
BLOCKED 线程阻塞等待监视器锁(synchronized)
WAITING 线程无限等待(如调用Object.wait())
TIMED_WAITING 线程等待指定时间(如Thread.sleep())
TERMINATED 线程执行完毕或异常终止

线程属性与控制

1. 线程优先级

1
2
3
thread.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级(10)
thread.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级(1)
thread.setPriority(Thread.NORM_PRIORITY); // 设置默认优先级(5)
  • 优先级只是建议,不保证执行顺序,不同操作系统实现不同

2. 线程名称

1
2
thread.setName("MyWorkerThread");
System.out.println(thread.getName()); // 输出线程名

3. 守护线程(Daemon Thread)

1
thread.setDaemon(true); // 设置为守护线程
  • 为其他线程服务的线程(如垃圾回收线程)
  • 当所有非守护线程结束时,JVM会自动终止守护线程

4. 线程中断

1
2
thread.interrupt(); // 中断线程
boolean isInterrupted = thread.isInterrupted(); // 检查是否被中断
  • 协作式中断:线程需自行检查中断状态并处理
  • 不推荐使用stop()suspend()resume()等已废弃方法

同步机制

1. 竞态条件(Race Condition)

  • 多个线程同时访问共享资源且执行顺序不确定,导致结果不可预测
  • 例:多个线程同时修改同一个计数器,可能导致计数丢失

2. synchronized关键字

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 方法级同步(锁当前对象)
public synchronized void increment() {
  count++;
}

// 代码块同步(锁指定对象)
public void increment() {
  synchronized (lockObject) {
      count++;
  }
}
  • 保证同一时间只有一个线程执行同步代码
  • 可重入:同一线程可多次获取同一把锁

3. 锁对象(Lock)(Java 5+):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
private Lock lock = new ReentrantLock();

public void increment() {
  lock.lock(); // 获取锁
  try {
      count++;
  } finally {
      lock.unlock(); // 释放锁(确保finally中调用)
  }
}
  • ReentrantLock:可重入锁,功能类似synchronized,但更灵活
  • ReentrantReadWriteLock:读写锁,允许多个读线程同时访问,写线程独占

4. 条件对象(Condition)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

public void await() throws InterruptedException {
  lock.lock();
  try {
      condition.await(); // 等待条件满足
  } finally {
      lock.unlock();
  }
}

public void signal() {
  lock.lock();
  try {
      condition.signal(); // 唤醒一个等待线程
      condition.signalAll(); // 唤醒所有等待线程
  } finally {
      lock.unlock();
  }
}
  • 配合锁使用,实现更精细的线程间通信

5. volatile关键字

1
private volatile boolean flag; // 保证可见性和禁止指令重排
  • 确保变量在多个线程间的可见性(一个线程修改后,其他线程立即可见)
  • 不保证原子性,适用于状态标记等简单场景,不适用于复合操作

线程安全集合

  • **并发包(Java.util.concurrent)**提供线程安全的集合:
集合类 特点 适用场景
ConcurrentHashMap 高效线程安全哈希表,分段锁机制 高并发读写,替代Hashtable
CopyOnWriteArrayList 写时复制,适合读多写少场景 事件监听、日志记录等
ConcurrentLinkedQueue 线程安全的链式队列,无锁实现 多线程间安全传递数据
BlockingQueue 阻塞队列,提供put()和take()等阻塞方法 生产者-消费者模型
ConcurrentSkipListMap 线程安全的有序Map,基于跳表实现 高并发下的有序数据访问
  • 使用示例

    1
    2
    3
    4
    
    // 使用ConcurrentHashMap
    Map<String, Integer> map = new ConcurrentHashMap<>();
    map.put("key", 1);
    int value = map.get("key");
    

任务与线程池

1. 执行器框架(Executor Framework)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 创建固定大小线程池
ExecutorService executor = Executors.newFixedThreadPool(5);

// 提交Runnable任务
executor.execute(() -> System.out.println("Task executed by thread pool"));

// 提交Callable任务(有返回值)
Future<String> future = executor.submit(() -> {
  // 执行任务
  return "Result";
});

// 关闭线程池
executor.shutdown(); // 等待现有任务完成后关闭
executor.shutdownNow(); // 立即关闭,尝试取消正在执行的任务

2. 线程池类型

  • newFixedThreadPool(int nThreads):固定大小线程池,重用固定数量线程
  • newCachedThreadPool():缓存线程池,按需创建线程,空闲线程会被回收
  • newSingleThreadExecutor():单线程执行器,保证任务按顺序执行
  • newScheduledThreadPool(int corePoolSize):定时线程池,支持任务定时或周期性执行

3. 控制任务组

1
2
3
4
5
// 提交多个任务并等待所有完成
List<Future<?>> futures = executor.invokeAll(tasks);

// 提交多个任务,返回第一个完成的任务结果
String result = executor.invokeAny(tasks);

异步计算

1. Future与Callable

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 提交Callable任务
Future<Integer> future = executor.submit(() -> {
  // 模拟耗时操作
  Thread.sleep(1000);
  return 42;
});

// 检查任务是否完成
boolean isDone = future.isDone();

// 获取结果(会阻塞直到任务完成)
int result = future.get();

// 获取结果(最多等待1秒)
int result = future.get(1, TimeUnit.SECONDS);

2. CompletableFuture(Java 8+):

  • 支持异步操作的链式调用和组合,无需显式线程管理

    1
    2
    3
    
    CompletableFuture.supplyAsync(() -> "Hello") // 异步执行任务
        .thenApply(s -> s + " World") // 处理结果
        .thenAccept(System.out::println); // 消费最终结果(无返回)
    

3. 异步计算最佳实践

  • 避免在UI线程执行耗时操作,使用线程池或CompletableFuture
  • 使用CompletableFuture处理多个异步任务的组合
  • 对长时间运行任务提供取消机制
  • 正确处理异常(使用exceptionally()handle()

第9-12章复习重点

  1. 集合框架

    • Collection与Map接口体系结构
    • 常用实现类特点与适用场景(如ArrayList vs LinkedList,HashMap vs TreeMap)
    • 迭代器使用与注意事项
    • Collections工具类方法
  2. GUI编程

    • Swing组件层次结构(容器与组件关系)
    • 布局管理器(FlowLayout、BorderLayout、GridBagLayout)使用
    • 事件处理机制(监听器、适配器)
    • 常用组件(JButton、JLabel、JTextField等)使用
  3. 并发编程

    • 线程创建方式(Thread、Runnable、Callable)
    • 线程同步机制(synchronized、Lock、Condition、volatile)
    • 线程池使用(Executor框架)
    • 线程安全集合与异步计算(Future、CompletableFuture)

提示:重点练习集合的实际应用、GUI布局设计和并发程序调试,这些是Java开发的核心技能,也是面试高频考点。

恍如昨日,嗤笑今朝
使用 Hugo 构建
主题 StackJimmy 设计