Mobile wallpaper 1
14410 字
72 分钟
期末·Java 程序设计基础

本文基于 Java 程序设计基础(第6版)(978-7-302-51551-7)进行编写,本文内容可能与课堂教学会存在偏差,请以课堂实际为准

第一章 Java 语言概述#

  1. 特点:简单易用,完全面对对象(OOP,特性:封装、继承、多态),分布式(数据分布和操作分布),与平台无关,安全可靠,多线程,主要面向 Internet
  2. 前身:Oak (Sun Microsystems)
  3. 技术方面:Java SE (基础标准版),Java ME(精简版,用于移动设备),Java EE(企业版,用于服务器端)
  4. Java 程序执行过程:先编译 ( *.java ) ,后解释 ( *.class )。 字节码是 JVM 的指令组,一次编写,到处运行。
  5. Java 程序结构:
    • package ch01 定义所属包: ch01
    • import java.util.* 导入 java.util.* 中的所有类
    • public class App1_1 定义类(当含有程序入口函数时作为主类,主类一般与程序文件同名且被定义为 public,一个源文件有且仅有一个 public 类;当没有 public 类时源文件可自由命名,但编译时必须使用 java 主类名
    • public static void main(String[] args) 定义主方法(程序入口)

第二章 Java 语言开发环境#

2.1 JDK#

  1. JDK 目录组成:
    • bin JDK 命令程序
    • conf Java 系统配置文件
    • include 本地开发与C语言相关头文件
    • jmods 预编译的 Java 模块
    • legal 协议
    • lib Java 类库
  2. JDK 命令程序组成:
    • javac.exe Java 编译器 ( *.java*.class )
    • java.exe Java 解释器 (*.class , *.java )
    • javadoc.exe 根据程序注释生成帮助文档的实用程序
    • javap.exe Java 反编译器 ( *.class*.java )
    • jdb.exe Java 调式器
    • jar.exe 生成 .jar 文件
    • jmod.exe 生成 .jmod 文件
  3. 环境变量
    • Java_Home JDK Path
    • ClassPath JVM 搜索类文件的路径 : %Java_Home%\lib
    • Path 环境变量: %Java_Home\bin

2.2 JDK 帮助文档下载与安装#

2.3 JDK 的使用#

第三章 Java 语言基础#

3.1 数据类型#

  1. 分类:基本类型(基本不可再分的类型,在内存存放的是数值本身)、引用类型(由多个基本类型组成,在内存存放的是数据地址。又称复合类型或指针)

  2. 基本类型分布:

    • 整数型: byte, short, int, long
    • 浮点型: float, double
    • 布尔型: boolean
    • 字符型: char
    类型占用字节
    boolean1
    byte1
    char2
    short2
    int4
    long8
    float4
    doule8

3.2 关键字与标识符#

  1. 标识符可以由:字母、数字(不能作为开头)、下划线和美元符号$组成

3.3 常量#

  1. 定义常量: 使用 final 关键字,类常量(在类而不是具体实例中共享)则使用 static final
  2. 字面量数值类型(literal): 整型常量( 100 , 长整型: 100L )、浮点型常量( 3.14 , 长浮点型 3.14F )

3.4 变量#

3.5 数据类型的转换#

  1. 类别: 自动类型转换、强制类型转换
  2. 自动类型转换关系: byte → short → char → int → long → float → double
  3. 字符串转换为数据类型: <Type>.parse<Type>(String s) (eg. Byte.parseByte(String s) )

3.6 局部变量的类型推断#

  1. 局部变量类型推断: var name = value ,如 var a = 21.0f 将被推断为 float 型

3.7 从键盘上输入数据#

3.7.1 BufferedReader (Java.io)#

BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String str = buf.readLine(); // throws IOException
char c = (char)buf.read();

3.7.2 Scanner (java.util)#

Scanner reader = new Scanner(System.in);
if(reader.hasNextDouble()){
double num = reader.nextDouble();
}
String str = reader.nextLine(); // catch white space character: ' ', '\t', '\f', '\r', '\n'
String str2 = reader.next(); // auto remove white space character before input valid data, exit only after input valid data

3.8 运算符和表达式#

  1. 除零错误: 当且仅当运算数都是整数时。

    5/0 // Error
    5.1/0 // Infinity
    -5.1/0 // -Infinity
    5.1%0 // NaN
  2. 一元运算符只能用于简单变量(如 ++(x+1) 是错误的)

  3. 等于运算符 == : 如果两个操作数都是数值变量,就算类型不同,只要值相等,运算结果就相等 (a == 97)。由于精度问题,不能直接比较浮点数,通常取一个较小的误差值求差判断浮点数之间是否相等

  4. 简洁运算符( && ) 可短路;非简洁运算符( & ) 必须完整计算

  5. 异或: 异值就是 true, 非异就 false

  6. 条件运算符: condition?true_value:false_value

第四章 流程控制#

4.1 语句和复合语句#

4.2 顺序结构#

4.3 分支结构#

  1. switch 语句

    switch(condition){ // condition support: byte, short, int, char, String, enum
    case value1:
    ... // do somethings.
    break;
    case value2:
    ... // do somethings.
    break;
    default:
    ... // do somethings.
    }

4.4 循环语句#

  1. while / do while 语句

    while(condition){
    ... // do somethings.
    }
    do{
    ... // do somethings.
    }while(condition); // cannot ignore ";"

4.5 循环中的跳转语句#

4.6 递归#

  1. 定义: 直接调用或间接调用自身的方法。
  2. 内存存储: 当方法调用自身时,在栈内存为新的局部变量和参数分配空间,并且使用这些新变量从头开始执行方法的代码。当每次递归调用返回时,将旧的局部变量和参数从栈中移出,并将执行控制恢复到方法内部的调用点。
  3. 特点:
    1. 递归方法中要有分支语句引导不同的情况
    2. 递归方法必须要有一个或多个终止条件用来停止递归
    3. 每次递归调用都会简化基础问题,直到变成基础情况为止

第五章 数组、字符串与正则表达式#

5.1 数组#

  1. 内存管理:

    1. 栈内存:基本类型的变量和对象的引用变量
    2. 堆内存:由 new 运算符创建的数组和对象
    3. 空引用型常量: null 表示该引用变量不指向任何对象
  2. 一维数组的定义:

    type[] name; // declare a array
    name = new type[count]; // allocate memory for a array
    // as same as:
    type[] name = new type[count];
    // use var
    var array = new type[count]; // true
    var[] array = new type[count]; // false
    // assignment init
    type[] name = {value1, value2, ...};
  3. java.util.Arrays 常用函数:

    • int binarySearch(Array, value) 在 Array 中搜索 value 并返回索引,不存在返回 -1
    • void sort(Array, <fromIndex>, <toIndex>) 字面意思
    • Type[] copyOf(Array, newLength) 字面意思
    • boolean equals(Array1, Array2) 字面意思
  4. foreach 循环

    for(type element: array){
    System.out.println(element);
    ...
    }
  5. 声明二维数组

    type[][] name;
    name = new type[x][y]; // x↓ y→
    // as same as:
    type[][] name = new type[x][y];
    // Irregular array
    type[][] name = new type[x][];
    name[0][] = new int[a];
    name[1][] = new int[b];
    ...
    name[n][] = null;
    // assignment init
    type[][] name = {
    {value1, value2, ...},
    {valuea, valueb, ...},
    ...
    }

5.2 字符串#

  1. 声明 String 变量(创建之后不可变)

    String str;
    str = new String("value");
    // as same as:
    String str = new String("value");
    // as same as:
    String str = "value";
    // calc
    str = str + "1" // not same memory, old was thrown.
  2. java.lang.String 常用方法:

    • int length()
    • boolean equals(Object)
    • boolean equalsIgnoreCase(String)
    • String substring(beginIndex, <endIndex>)
    • char charAt(index)
    • void getChars(srcBegin, srcEnd, char[] dst, dstBegin) 将字符串索引 srcBeginsrcEnd 之间的字符放入到字符数组 dst 的索引 dstBegin
    • int indexOf(String/char)
    • int lastIndexOf(String/char)
    • boolean startsWith(String)
    • boolean endsWith(String)
    • int compareTo(String)
    • int compareToIgnoreCase(String)
    • String replace(oldString, newString)
    • boolean matches(regex) 匹配正则表达式
    • String trim() 去除首尾空格
    • String[] split(regex, limit=0) 字面意思。当 limit<=0 时,字符串被尽可能分割,但当 limit=0 时,会自动去除尾部空白字符
    • String toLowerCase()
    • String toUpperCase()
  3. 声明 StringBuffer 变量(创建之后可变,可自动增长)

    StringBuffer strBuf = new StringBuffer()
    // equal to
    StringBuffer strBuf = new StringBuffer(16) // length: 16
    StringBuffer strBuf = new StringBuffer(String)
  4. java.lang.StringBuffer 常用方法:

    • int capacity() 获取容量
    • void ensureCapacity(capacity) 设置容量
    • StringBuffer append(strBuf)
    • StringBuffer insert(offset, str)
    • StringBuffer delete(start, end)
    • StringBuffer deleteCharAt(index)
    • StringBuffer reverse()
    • String substring(start, end)

5.3 正则表达式#

  1. 元字符
元字符匹配元字符匹配
^字符串起始\p{Upper}大写字母
$字符串结尾\p{Alpha}字母
.任何一个字符\p{ASCII}ASCII
\bborder单词边界\p{Digit}数字
\Bnon-border\p{Alnum}字母或数字
\ddigit\p{Punct}标点符号
\Dnon-digit\p{Graph}可见字符(Alnum + Punct)
\sspace空格类字符\p{Print}可打印字符
\Snon-space\p{Cntrl}控制字符
\wword, az, AZ, 0~9\p{XDigit}十六进制数字
\Wnon-word\p{Space}空字符
\p{Lower}小写字母
  1. java.util.regex.Pattern 常用函数:

    • Pattern compile(regex, <int flags>) 编译表达式, flags 作为匹配模式,其取值是 Pattern 类中定义的常量
    • Matcher matcher(input) 创建 Matcher 对象
    • String pattern() 返回表达式的字符串表示形式,即 compile(regex) 中的 regex
    • String toString() 返回表达式的字符串表示形式
    • String[] split(input, limit=0)
    • String quote(String) 返回只匹配该字符串的表达式
  2. java.util.regex.Matcher 常用函数:

    • boolean matches() 是否完全匹配
    • boolean find(<startIndex>) 逐一匹配,可重复调用
    • String group() 返回匹配到的字符串
    • boolean lookingAt() 在前面的字符串进行匹配
    • int start() 返回匹配字符串的首索引
    • int end() 返回匹配字符串的尾索引
    • String replaceAll(String)
    • String replaceFirst(String)
  3. 用例

    String email = "i@snowy.moe"
    Pattern pa = Pattern.compile("^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$")
    Matcher ma = pa.matcher(email)
    System.out.println(ma.matches()) // true

第六章 类与对象#

6.1 类的基本概念#

  1. 类与对象的差别

    项目类(Class)对象(Object)
    定义类是对一类事物的抽象,是对象的模板或蓝图。对象是类的一个实例,是真实存在的个体。
    作用描述对象的属性(字段)和行为(方法)。实际执行操作,代表某一个具体的事物。

6.2 定义类#

  1. 类修饰符

    修饰符含义
    public可被任意对象访问的公共类
    abstract抽象类
    final不能被继承的最终类
    只能在当前包中被访问的类
  2. 成员变量修饰符

    修饰符含义
    public可被任意对象访问的公共变量
    private只允许自身访问
    protected只允许自身和子类访问
    包内可访问
    final常量
    static共享变量
    transient保留变量,暂无特别作用
    volatile可多线程同时控制的变量
  3. 成员方法修饰符

    修饰符含义
    public可被任意对象访问的公共方法
    private只允许自身访问
    protected只允许自身和子类访问
    包内可访问
    final最终方法,不可修改
    static静态方法,无需初始化实例即可调用
    abstract抽象方法,子类必须实现
    synchronized同步方法,在多线程中对同步资源加锁
    native本地方法,方法体是用其他语言在外部编写的

6.3 类的 UML 图#

  1. 访问权限表示: + pubic - private ## protected
  2. 关系:
    1. 类的关联: A —> B ,表示 A 中的成员变量引用了 B
    2. 类的依赖: A - - > B,表示 A 中的方法操作了 B

6.4 对象的创建和引用#

  1. this 显式引用当前对象的成员; super 引用父类对象成员

6.5 参数的传递#

  1. 可变长度参数

    public static void display(String str, String...args){
    System.out.println(str);
    for(String arg:args){
    System.out.println(arg);
    }
    }
    public static void main(String[] args){
    display("Hello");
    display("Hello", "world");
    display("Hello", "world", "!");
    ...
    }

6.6 匿名对象#

第七章 Java 类的特性#

7.1 类的私有成员与公共成员#

7.2 方法的重载#

(public) (void) setValue(){ // 仅靠参数列表判断重载
this.value = 0;
}
(public) (void) setValue(int value){
this.value = value;
}
// Error:
public void setValue(int value1, double value2);
public void setValue(double value1, int value2);

*重写父类方法或实现接口中的方法时需要使用 @Override

7.3 构造方法#

  1. 特点

    1. 构造方法的方法名与类名相同
    2. 构造方法没有返回值,也不能用 void 作为无返回值类型(其本质是返回自身)
    3. 不能显式调用,而只能使用 new 间接调用
    4. 如果不显式声明构造方法,则编译器会自动生成一个无参构造方法。当声明了一个有参构造方法当没有声明无参构造方法时,编译会不通过。
  2. 实例:

    public class Coordinate{
    int x;
    int y;
    public Coordinate(){ // 当标识为 private 时无法在外部完成初始化
    this(0, 0); // place it first when use this.
    // x = 0;
    // y = 0;
    }
    public Corrdinate(int x, int y){
    this.x = x;
    this.y = y;
    }
    }

7.4 静态成员#

  1. 静态变量: 在每个类实例都互相共享的变量
  2. 静态方法: 属于类的静态方法而不是某个具体对象,不能使用 superthis
  3. 主方法的定义: public 确保可在类外调用; static 确保可在不初始化类时调用
  4. 静态初始化器: static {...} 在类被加载进内存时使用,只调用一次

7.5 对象的应用#

  1. 对象的比较: class1 == class2 表示两个引用变量所指向的实例地址相同; class1.equals(class2) 通过父类 Object.equals 判断是否相同,默认行为为 ==

7.6 基本类型与包装类类型之间的自动转换#

  1. 将基本类型封装到包装类:

    Integer iOb = Integer.valueOf(100);
    int value = iOb.intValue();
    // auto(un)boxing:
    Integer iOb = 100;
    int value = iOb;

7.7 Java 语言的垃圾回收机制#

  1. 通过引用计算器判断是否进行垃圾回收。增加一次引用就加1,减少一次就减1,当引用数为0时可以在某时进行垃圾回收。

第八章 继承、抽象类、接口与枚举#

8.1 类的继承#

  1. 子类的创建

    class SubClass extends SuperClass{
    public SubClass(){ // 严格意义上,构造方法是不能被继承的。且父类的无参构造方法会在子类中被默认调用
    // super() // 自动初始化,除非显式调用了 super
    ...
    }
    }
  2. 子类的覆盖

    public class Coordinate{
    protected int x; // public or protected,
    protected int y; // not private.
    ...
    public void show(){
    System.out.println(x);
    System.out.println(y);
    }
    }
    class MyCoordinate extends Coordinate{
    ...
    @overriding
    public void show(){ // 子类中不能覆盖 final 和 static 方法
    System.out.printf("x=%d, y=%d", x, y);
    // super.show();
    }
    }
  3. Object 类常用方法:

    • boolean equals(obj) 相当于 == 运算符。在字符串中由于存在一个字符串池,初始化时先去字符串池中寻找是否有值相同字符串,如果有就返回,所以即使初始化的时机不同,只要值相同,就为 true
    • String toString()
    • final Class getClass() 返回对象所属的类
    • Object clone()
  4. instanceof

    相当于 Python 中的 isinstance ,用法: value instanceof class

8.2 抽象类#

  1. 声明:

    abstract class Obj{ // 无法用 new 初始化
    protected Type value;
    ...
    abstract Type func(...); // 抽象方法没有方法体
    }

8.3 接口#

  1. 声明:

    [public] interface Obj [extends PObj1, PObj2, ...]{
    [public static final] Type NAME = VALUE;
    ...
    [public abstract] Type func(para, ...);
    ...
    private Type privateFunc(para, ...){
    ...
    }
    ...
    public static Type staticFunc(para, ..){
    ...
    }
    public default Type defaultFunc(para, ...){
    ...
    }
    }
  2. 实现接口:

    class MyObj implements Obj, Obj2, ...{
    ...
    }
  3. 解决父接口冲突:

    默认方法(使用 default 并给出具体实现的方法)优先,其次是子接口优先。

    interface A {
    default void greet() {
    System.out.println("Hello from A");
    }
    }
    interface B {
    default void greet() {
    System.out.println("Hello from B");
    }
    }
    class MyClass implements A, B {
    // ❌ 编译错误:greet() 有冲突,必须手动解决
    @Override
    public void greet() {
    // ✅ 显式指定要调用哪个接口的默认方法
    A.super.greet(); // or B.super.greet();
    }
    }
  4. 接口与抽象类:

    特性/区别抽象类 (abstract class)接口 (interface)
    是否可以有方法实现✅ 可以有方法实现✅ 从 Java 8 开始可以有 defaultstatic 方法
    是否可以有成员变量✅ 可以有实例变量(包括 private, protected⛔ 只能有 public static final 常量(即常量)
    构造函数✅ 可以有构造函数⛔ 不能有构造函数
    多继承⛔ 只能单继承✅ 支持多接口实现
    访问修饰符✅ 可以使用 private, protected✅ 接口方法默认是 public
    继承/实现关键字extendsimplements
    使用目的表示“某一类事物的通用特性”表示“某种能力或行为”
    默认方法⛔ 没有(除非是普通方法)default 方法(Java 8+)
    是否可被实例化⛔ 不能⛔ 不能

8.4 枚举#

  1. 定义:

    [public] enum Enum{NAME1(VALUE1), NAME2(VALUE2), NAME(VALUE3);}
  2. 实例:

    public enum Color {
    RED("红色"),
    GREEN("绿色"),
    BLUE("蓝色");
    private String description;
    private Color(String description) {
    this.description = description;
    }
    public String getDescription() {
    return description;
    }
    }
    Color c = Color.RED;
    System.out.println(c.getDescription()); // 输出:红色
  3. 特性:

    1. 枚举是一个类,但它不能再被继承
    2. 枚举常量本质是枚举类型的实例对象,每个枚举值都相当于 public static final 的对象
    3. 枚举可以添加字段、构造方法和方法,但构造方法必须是私有的
  4. java.lang.annotation.ElementType (枚举类)常用方法:

    • enumtype[] values() 返回枚举类型的数组
    • enumtype valueOf(name) 返回名称为 name 的枚举成员
  5. java.lang.Enum<E> (枚举成员)常用方法:

    • int compareTo(E member) 枚举成员间的比较
    • String name() 返回枚举常量名,即定义时的标识符(不可重写)
    • int ordinal() 返回枚举成员序号
    • boolean equals(Object other) 比较两个枚举引用的对象是否相等
    • String toString() 默认返回常量名,与 name() 相同

8.5 包#

  1. 包声明: package com.company.package 。其值与文件夹的次序一致。Java 将在环境变量 ClassPath 中寻找这些包

  2. 当缺失包声明时,Java 会默认将其放入到默认包中,容易发生命名空间问题

  3. Java 常用包:

    • java.lang 语言包。包含各种类,如 ObjectString
    • java.io 输入输出流包
    • java.util 实用包
    • java.net 网络功能包
    • java.sql 数据库连接包
    • java.text 文本包
  4. Java 常用类:

    • java.util.Date 描述时间和日期
    • java.util.Calendar 描述日期时间,适用于将日期值分解的情况
    • java.util.Random 随机类
    • java.lang.Math 数学类
    • java.text.DecimalFormat 格式化十进制数字类
  5. 导入包: import com.company.package;

    或者使用外部包时指定全称: class myDate extends java.util.Date

第九章 异常处理#

9.1 异常处理的基本概念#

9.2 异常处理类#

  1. 异常类的层次结构

    异常类的层次结构

    在异常的上层有一个 java.lang.Throwable 对象,派生了 ErrorException 两个类。拥有常用方法:

    • getMessage()
    • toString() return: "ExpectionName: getMessage()"
    • printStackTrace()
    • StackTraceElement[] getStrackTrace()

    其中 Error 为系统保留,代表内部系统错误, Exception 由应用程序使用,可以由以下方法构建:

    public Exception(<String message>)
  2. 受检异常:

    • 是 Java 中强制编译器检查的异常。
    • 它们都直接或间接继承自 java.lang.Exception,但不包括 RuntimeException 及其子类。
    • 示例包括:
      • IOException
      • SQLException
      • FileNotFoundException
      • ClassNotFoundException
      • etc.

9.3 异常的处理#

  1. 捕获异常

    try{
    ...
    }catch(Exception1 | Exception2 e){
    ...
    }finally{
    ...
    }

9.4 抛出异常#

  1. 抛出异常

    public func() throws Exception1, Exception2, ...{ // 声明函数可能会抛出的异常
    throw new Exception();
    }

9.5 多重捕获异常#

9.6 自动关闭资源的 try 语句#

  1. try-with-resources 语句:

    public func() throws IoException{
    try(Scanner in = new Scanner(System.in)){ // try() 中的资源会自动释放
    ... // 前提是该资源继承于 java.lang.AutoCloseable
    } // AutoCloseable.close()
    }

9.7 自定义异常类#

  1. 继承 Exception 类

    class MyException extends Exception{
    String message;
    MyException(String m){
    message = m;
    }
    public String toString(){
    return message;
    }
    }

第十章 Java 语言的输入输出与文件管理#

10.1 Java 语言的输入输出#

  1. Java 输入输出基本类(抽象类)
    • 输入流
      • 字节流: InputStream
      • 字符流: Reader
    • 输出流
      • 字节流: OutputStream
      • 字符流: Writer

输入输出基本类(抽象类)

10.2 使用 InputStream 和 OutputStream 类#

  1. InputStream 类常用方法:

    • int read() 读入一字节的二进制数据,并与八个全为零的高位字节组合成16位的整形量返回(byte 最大值为 128 而不是 256)。-1 表示当前位置没有数据
    • int read(byte[] b, <int off=0> <int len=1>) 读取 len 长度的字节并放入到 b 列表中,从索引 off 开始存放,返回读取到的字节数
    • int available() 返回剩余可读取到的字节数
    • long skip(long n) 让位置指针向后跳过 n 字节
    • mark(int readlimit) 在当前位置做一个标记,并在读取超过 readlimit 后失效
    • reset() 让位置指针回到标记位置
    • close()
  2. OutputStream 类常用方法:

    • write(int b) 将 b 中的低位字节写入输出流
    • write(byte[] b, <int off> <int len>)
    • flush() 强制清空缓存区并执行写操作。写入流是先存放到缓冲区再当一定数量时再写入外设上的。
    • close()
  3. FileInputStream 类构造方法: FileInputStream(String name | File file | FileDescriptor fdObj)

  4. FileOutputStream 类构造方法: FileOutputStream(String name, <Boolean append> | File file | FileDescriptor fdObj)

  5. 顺序输入流 SequenceInputStream ,可将多个数据流合并为单一的输入数据流。

    构造方法:

    SequenceInputStream(InputStream s1, s2 | Enumeration<? extends InputStream> e)

  6. 管道输入输出流 PipedInputStream PipedOutputStream , 可将一个程序或线程的输出连接到另外一个程序或线程作为输入

    构造方法:

    • PipedInputStream(<PipedOutputStream src>, <int pipeSize>)
    • PipedOutputStream(<PipedInputStream snk>)

    常用特殊方法:

    • PipedInputStream.connect(PipedOutputStream src)
    • PipedOutputStream.connect(PipedInputStream snk)

10.3 使用 Reader 和 Writer 类#

  1. 过滤输入输出流 FilterInputStream FilterOutputStream ,分别实现了在数据的读、写操作的同时进行数据处理

    构造方法:

    • DataInputStream(InputStream in)
    • DataOutputStream(OutputStream out)

    常用特殊方法:

    • public boolean readBoolean()
    • public byte readByte()
    • public char readChar()
    • public short readShort()
    • public int readInt()
    • public float readFloat()
    • public long readLong()
    • public double readDouble()

    • public void writeBoolean(boolean v)
    • public void writeByte(int v)
    • public void writeChar(int v)
    • public void writeShort(int v)
    • public void writeInt(int v)
    • public void writeFloat(float v)
    • public void writeLong(long v)
    • public void writeDouble(double v)
    • int size() 返回写入的字节数
  2. Reader 类(抽象类)的常用方法

    • public int read() 从输入流中读一个字符
    • public int read(char[], <int off=0>, <int len>)
    • public int read(char[])
    • public long skip(long n)
    • public boolean ready() 判断流是否做好读的准备
    • public void mark(int readAheadLimit)
    • public boolean markSupported() 测试输入流是否支持 mark
    • public void reset()
    • public void close()
  3. Writer 类(抽象类)的常用方法

    • public void write(int c)
    • public void write(String str)
    • public void write(char[] cbuf, int off, int len)
    • public void flush()
    • public void close()
    • public Writer append(char c | CharSequence csq, <int start>, <int end>)

第十一章 泛型与容器类#

11.1 泛型#

  1. 实质: 将数据类型参数化,通过为类、接口及方法设置类型参数来定义泛型

  2. 命名规范:

    类型参数含义
    TType(类型)
    EElement(集合元素)
    KKey(键)
    VValue(值)
    NNumber(数字)

11.1.1 泛型类#

  1. 定义: class ClassName<T>

    public class Box<T> {
    private T item;
    public void setItem(T item) {
    this.item = item;
    }
    public T getItem() {
    return item;
    }
    }
    public class Pair<K, V> {
    private K key;
    private V value;
    public Pair(K key, V value) {
    this.key = key;
    this.value = value;
    }
    public K getKey() { return key; }
    public V getValue() { return value; }
    }
  2. 实例化: ClassName<类型实参列表> classname = new ClassName<>(args)

    Box<String> stringBox = new Box<>();
    stringBox.setItem("Java");
    String item = stringBox.getItem();
    Pair<String, Integer> pair = new Pair<>("Age", 25);
    System.out.println(pair.getKey() + ": " + pair.getValue());

11.1.2 泛型方法#

  1. 定义: <T> Type FuncName(T args)

    public <T> void methodName(T parameter) {
    // 方法体
    }
    public class GenericMethodExample {
    public static <T> void printArray(T[] array) {
    for (T element : array) {
    System.out.println(element);
    }
    }
    public static void main(String[] args) {
    Integer[] intArray = {1, 2, 3};
    String[] strArray = {"a", "b", "c"};
    printArray(intArray); // T 被推断为 Integer
    printArray(strArray); // T 被推断为 String
    }
    }
  2. 带返回值的泛型方法:

    public class ArrayUtils {
    public static <T> T getFirstElement(T[] array) {
    if (array == null || array.length == 0) {
    return null;
    }
    return array[0];
    }
    public static void main(String[] args) {
    String[] names = {"Tom", "Jerry"};
    Integer[] numbers = {1, 2, 3};
    String firstStr = getFirstElement(names);
    Integer firstInt = getFirstElement(numbers);
    System.out.println(firstStr);
    System.out.println(firstInt);
    }
    }

11.1.3 限制泛型的可用类型#

1. 上界限制:<T extends Number>

public static <T extends Number> double sum(T[] numbers) {
double total = 0;
for (T num : numbers) {
total += num.doubleValue();
}
return total;
}

只能传入 Number 的子类数组,如 Integer[]Double[]

2. 多重边界限制(Multiple Bounds)

<T extends Comparable & Serializable>

表示 T 必须同时是 ComparableSerializable 的子类。

11.1.4 通配符与边界限制#

1. 无界通配符:<?>

表示未知类型:

public static void printBox(Box<?> box) {
System.out.println(box.getItem());
}

2. 上界通配符:<? extends T>

只能传入 T 或其子类:

List<? extends Number> numbers = new ArrayList<Integer>();

3. 下界通配符:<? super T>

只能传入 T 或其父类:

List<? super Integer> list = new ArrayList<Number>();

11.1.5 泛型接口#

  1. 定义: interface InterfaceName<T>

    public interface Container<T> {
    void set(T item);
    T get();
    }
  2. 实现:

    public class Box<T> implements Container<T> {
    private T item;
    public void set(T item) {
    this.item = item;
    }
    public T get() {
    return item;
    }
    }
    public class StringContainer implements Container<String> {
    private String item;
    public void set(String item) {
    this.item = item;
    }
    public String get() {
    return item;
    }
    }

11.2 容器类#

  1. 定义: 容器类是 Java 以类库形式供用户开发程序时可直接使用的各种数据结构

容器框架基本类及其实现类

11.2.1 Collection 接口#

常用方法功能说明
int size()返回容器中元素的个数
boolean isEmpty()判断容器是否为空
boolean contains(Object obj)判断容器是否包含元素obj
boolean add(E element)向容器中添加元素element,添加成功返回true;若容器中已包含element,且不允许有重复元素,则返回false
int hashCode()返回容器的哈希码值
Object toArray()将容器转换为数组,返回的数组包含容器的所有元素
boolean remove(Object obj)从容器中删除元素obj,删除成功返回true;若容器不包含obj,则返回false
void clear()删除容器中的所有元素
Iterator iterator()返回容器的迭代器
boolean equals(Object o)比较此collection与指定对象o是否相等
void shuffle(List <?> list)以随机方式重排list中的元素,即洗牌
boolean containsAll(Collection <?>c)判断当前容器是否包含容器c中的所有元素
boolean addAll(Collection <? extends E> c)将容器c中的所有元素添加到当前容器中,集合并运算
boolean removeAll(Collection <?>c)在当前容器中删除包含在容器c中的所有元素,集合差运算
boolean retainAll(Collection <?>c)仅保留当前容器中也被容器c包含的元素,即删除当前容器中未被包含在容器c中的所有元素,集合交运算
void rotate(List<?> list, int distance)列表中的元素按指定距离进行旋转(正数表示向右旋转,负数表示向左旋转)

11.2.2 List 接口#

常用方法功能说明
E get(int index)返回列表中指定位置的元素
E set(int index, E element)用元素element取代index位置的元素,返回被取代的元素
int indexOf(Object o)返回元素o首次出现的序号,若o不存在返回-1
int lastIndexOf(Object o)返回元素o最后出现的序号
void add(int index, E element)在 index 位置插入元素 element
boolean add(E element)在列表的最后添加元素 element
E remove(int index)在列表中删除index位置的元素
boolean addAll(Collection <? extends E> c)在列表的最后添加容器c中的所有元素
boolean addAll(int index, Collection <? extends E> c)在 index位置按照容器c中元素的原有次序插入c中所有元素
ListIterator listIterator()返回列表中元素的列表迭代器
ListIterator listIterator(int index)返回从index位置开始的列表迭代器
ListIterator listIterator(List.size())返回最后一个元素的后面开始反向遍历的列表的列表迭代器

实现List接口的类主要有两个:链表类 LinkedList 和数组列表类 ArrayList 。它们都是线性表。

特性ArrayList<E>LinkedList<E>
底层结构动态数组双向链表(Doubly Linked List)
是否线程安全❌ 不是线程安全❌ 不是线程安全
元素访问方式支持快速随机访问(通过索引)不支持高效随机访问
插入/删除效率在中间或开头插入删除(慢,需要移动元素)在任意位置插入删除(快)
内存占用较小稍大(每个节点额外保存前后指针)

使用场景对比

场景推荐使用
频繁读取元素(如遍历、按索引访问)ArrayList
频繁在中间或头部插入/删除元素LinkedList
只在尾部进行增删操作ArrayList(两者性能接近)
需要作为栈、队列、双端队列使用LinkedList(它实现了**Deque**接口)

ArrayList 常用方法

方法功能
add(E element)添加元素到末尾
add(int index, E element)在指定索引插入元素
get(int index)获取指定索引的元素
set(int index, E element)替换指定位置的元素
remove(int index)删除指定索引的元素
remove(Object o)删除第一次出现的指定元素
size()返回集合中元素的数量
isEmpty()判断集合是否为空
contains(Object o)判断是否包含某个元素
clear()清空所有元素

扩展功能(LinkedList 特有)

LinkedList 还实现了 Deque<E> 接口,因此可以当作 双端队列 使用:

方法功能
addFirst(E e)添加到头部
addLast(E e)添加到尾部
removeFirst()移除头部
removeLast()移除尾部
getFirst()获取头部
getLast()获取尾部

11.2.3 Iterator 接口#

1. 概述

  • 作用 :主要用于遍历集合(如 ListSetQueue 等)中的元素。
  • 特点
    • 只能单向遍历 (从前往后)。
    • 支持在遍历过程中删除当前元素(通过 remove() 方法)。
    • 不支持添加、替换等操作。
  • 适用于所有实现了 Iterable 接口的集合类

2. 常用方法

方法名描述
hasNext()判断是否还有下一个元素
next()返回下一个元素
remove()删除上一次调用**next()**返回的元素(可选操作)

3. ListIterator<E>

1. 概述

  • 作用 :专门用于遍历 List 集合的迭代器。
  • 特点
    • 支持双向遍历 (向前和向后)。
    • 支持读取、添加、修改和删除操作。
    • 提供了索引信息(可以知道当前元素的位置)。
  • 只能用于 List 类型的集合

2. 常用方法

方法名描述
hasNext()是否有下一个元素
next()获取下一个元素
nextIndex()返回下个元素的索引
hasPrevious()是否有前一个元素
previous()获取前一个元素
previousIndex()返回前一个元素的索引
add(E e)在当前位置前插入元素
set(E e)替换最后一次调用**next()previous()**的元素
remove()删除最后一次调用**next()previous()**的元素
  1. 对比总结
特性Iterator<E>ListIterator<E>
遍历方向单向(从前往后)双向(前后均可)
可操作集合类型所有**Iterable**集合(如 Set、List、Queue)仅限**List**
添加元素❌ 不支持✅ 支持(通过**add()**)
修改元素❌ 不支持✅ 支持(通过**set()**)
删除元素✅ 支持(通过**remove()**)✅ 支持(通过**remove()**)
获取索引❌ 不支持✅ 支持(nextIndex()/previousIndex()

11.2.4 Set 接口#

  1. 定义: 用于存储无序、不重复 的元素集合。它定义了一组不允许重复元素的集合操作。

  2. 特点

    • 无序性 :元素没有固定的顺序(不同于 List)。
    • 唯一性 :不允许有重复元素(通过 equals()hashCode() 方法判断是否重复)。
    • 不允许 null 元素多次添加(但某些实现类如 HashSet 可以添加一个 null)。
  3. 常用方法

    方法描述
    add(E e)添加元素(如果不存在)
    addAll(Set<?> set)合并集合
    remove(Object o)删除指定元素
    contains(Object o)判断是否包含某元素
    size()返回集合大小
    isEmpty()判断是否为空
  4. HashSet

    1. 定义: 通过哈希码存储集合中的元素
    2. 特点:
      • 基于哈希表(HashMap 实现),性能高。
      • 无序 (插入顺序 ≠ 遍历顺序)。
      • 允许一个 null 元素。
      • 线程不安全。
    3. 常用方法:
      • boolean add(E e) 添加元素,若该元素存在则返回 False
      • void clear() 清空集合中的所有元素
      • boolean contains(Object O)
      • int size() 返回实际元素个数
  5. TreeSet

    1. 定义: 基于红黑树实现,有序排列的集合
    2. 特点:
      • 基于红黑树(NavigableMap 实现)。
      • 自然排序 或自定义排序(通过 Comparator)。
      • 不允许 null(会抛出异常)。
      • 支持范围查询、获取最大/最小值等操作。
      • 性能低于 HashSet,但支持排序。
    3. 常用方法:
      • E first()
      • E last()
      • E lower(E e) 返回严格小于 e 的最大元素,否则返回 null
      • E higher(E e)
      • E floor(E e) 返回小于等于 e 的最大元素,否则返回 null
      • E ceiling(E e)
      • SortedSet<E> headSet(E toElement) 返回含有 toElement 之前(不包含)所有元素的集合
      • SortedSet<E> tailSet(E fromElement) 返回含有 toElement 之后(包含)所有元素的集合
      • SortedSet<E> subSet(E fromElement, E toElement) 返回 [ fromElement, toElement) 所有元素的集合

11.2.5 Map<K, V> 接口#

  1. 用于存储键值对(Key-Value Pair)的接口

  2. 定义

    public interface Map<K,V>
    • K 表示键(Key)的类型。
    • V 表示值(Value)的类型。
  3. 特点:

    特性描述
    键唯一每个键(Key)在 Map 中是唯一的,不能重复。如果添加相同的 Key,新的 Value 会替换旧的 Value。
    无序或有序不同实现类决定是否保持顺序(如**HashMap无序,LinkedHashMap**保持插入顺序)。
    支持 null大多数实现允许一个 null 键和多个 null 值(具体取决于实现类)。

4 .基本操作方法:

方法描述
put(K key, V value)添加或更新一个键值对
get(Object key)根据键获取对应的值
remove(Object key)删除指定键的键值对
containsKey(Object key)判断是否包含某个键
containsValue(Object value)判断是否包含某个值
size()返回键值对的数量
isEmpty()判断是否为空
keySet()获取所有键的 Set 集合
values()获取所有值的 Collection 集合
entrySet()获取所有键值对的 Set 集合(每个元素是一个**Map.Entry<K, V>**)
  1. HashMap<K, V>:
    1. 特点
      • 基于哈希表实现,性能高。
      • 无序 (不保证键值对的顺序)。
      • 允许一个 null 键和多个 null 值。
      • 线程不安全。
  2. LinkedHashMap<K, V>:
    1. 特点:
      • 继承自 HashMap
      • 使用双向链表维护插入顺序或访问顺序。
      • 有序 (默认按插入顺序)。
      • 性能略低于 HashMap
    2. 常用方法:
      • K firstKey()
      • K lastKey()
      • SortedMap<K, V> headMap(K toKey)
      • SortedMap<K, V> tailMap(K fromKey)
      • K lowerKey(K key)
      • K higherKey(K Key)
      • K floorKey(K key)
      • K ceilingKey(K key)

第十二章 内部类、匿名内部类、Lambda 表达式与方法引用#

12.1 内部类与匿名内部类#

  1. 内部类:

    1. 定义:定义在类中的类

    2. 示例:

      public class Outer {
      private String msg = "I am Outer Class";
      // 成员内部类
      class Inner {
      private String msg = "I am Inner Class";
      void display() {
      System.out.println(this.msg);
      System.out.println(Outer.this.msg); // 可以访问外部类的私有变量
      }
      }
      public static void main(String[] args) {
      Outer outer = new Outer();
      Outer.Inner inner = outer.new Inner(); // 创建内部类对象,必须依附于外部类的实例
      inner.display();
      }
      }
  2. 静态内部类:

public class Outer {
private static String msg = "Static Inner Class";
static class StaticInner {
void display() {
System.out.println(msg); // 只能访问外部类的静态成员
}
}
public static void main(String[] args) {
StaticInner inner = new StaticInner(); // 不需要外部类实例
inner.display();
}
}
  1. 局部内部类:

    public class Outer {
    void outerMethod() {
    String msg = "Local Inner Class";
    class LocalInner {
    void display() {
    System.out.println(msg);
    }
    }
    LocalInner localInner = new LocalInner();
    localInner.display();
    }
    public static void main(String[] args) {
    Outer outer = new Outer();
    outer.outerMethod();
    }
    }
  2. 匿名内部类:

    1. 定义:没有名字的内部类,通常用于简化实现接口或抽象类的子类 ,常用于事件监听、线程等场景。

    2. 语法:

      new 父类构造器(参数列表) 或 接口名() {
      // 类体
      }
    3. 基于抽象类的匿名内部类:

      abstract class Animal {
      abstract void speak();
      }
      public class AnonymousExample {
      public static void main(String[] args) {
      // 匿名内部类继承抽象类
      Animal animal = new Animal() {
      @Override
      void speak() {
      System.out.println("Animal speaks!");
      }
      };
      animal.speak();
      }
      }

12.2 函数式接口与 Lambda 表达式#

  1. 函数式接口(单抽象方法接口):

    1. 定义:只包含一个抽象方法的接口,可以使用注解 @FunctionalInterface 来明确声明该接口是一个函数式接口(非强制,但推荐使用)。

    2. 示例:

      @FunctionalInterface
      public interface MyFunctionalInterface {
      void doSomething(); // 唯一的抽象方法
      default void defaultMethod() {
      System.out.println("Default method");
      }
      static void staticMethod() {
      System.out.println("Static method");
      }
      }
  2. Lambda 表达式

    1. 定义:Lambda 表达式是一个匿名函数 ,可以把它理解为一段没有类名、方法名的代码块,可以作为参数传递给方法或赋值给变量。它可以简化对函数式接口的实现

    2. 语法:

      (parameters) -> { statements; }
    3. 示例:

      interface MathOperation {
      int operate(int a, int b);
      }
      public class LambdaExample {
      public static void main(String[] args) {
      MathOperation add = (a, b) -> a + b;
      MathOperation multiply = (a, b) -> a * b;
      System.out.println(add.operate(3, 4)); // 输出 7
      System.out.println(multiply.operate(3, 4)); // 输出 12
      }
      }
    4. Lambda 表达式结合内置函数式接口使用:

      1. Consumer<T>:消费型接口:

        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        names.forEach(name -> System.out.println("Name: " + name));

        等价于:

        names.forEach(new Consumer<String>() {
        @Override
        public void accept(String name) {
        System.out.println("Name: " + name);
        }
        });
      2. Predicate<T>:判断型接口

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream()
        .filter(n -> n % 2 == 0)
        .forEach(System.out::println); // 输出 2 和 4
      3. Function<T, R>:转换型接口

        List<String> words = Arrays.asList("apple", "banana", "cherry");
        List<Integer> lengths = words.stream()
        .map(word -> word.length())
        .toList();
        System.out.println(lengths); // 输出 [5, 6, 6]
  3. 方法引用:

    1. 定义:Lambda 表达式还可以进一步简化为方法引用 ,适用于已有方法满足需求的情况。

    2. 语法:

      • 类名::静态方法
      • 对象::实例方法
      • 类名::实例方法
    3. 示例:

      List<String> list = Arrays.asList("a", "b", "c");
      // 使用 Lambda
      list.forEach(item -> System.out.println(item));
      // 使用方法引用
      list.forEach(System.out::println);

复习提纲#

第一章 Java 语言概述#

  1. 什么是平台无关性、编译与解释并存, Java是如何实现“一次编写,到处运行”?

    平台无关性:程序可以在任何支持Java虚拟机(JVM)的设备上运行,无需修改代码。

    编译与解释并存:Java源代码先被编译成字节码(.class文件),然后由JVM在目标平台上解释执行。

    由于字节码是与平台无关的中间代码,只要设备安装了相应的JVM,就能运行Java程序,从而实现“一次编写,到处运行”。

  2. 面向对象的基本特征。

  • 封装 :将数据和行为包装在类中,对外隐藏实现细节,只暴露必要的接口。
  • 继承 :子类可以继承父类的属性和方法,实现代码复用和层次关系表达。
  • 多态 :同一接口可有多种实现方式,通常通过方法重写(运行时多态)体现。
  • 抽象 :提取关键特征,忽略复杂实现,帮助构建更清晰的逻辑模型。
  1. 什么是Java虚拟机?什么是字节码,以及字节码的好处?

    Java虚拟机:运行Java程序的虚拟计算机,它负责加载、验证和执行字节码。

    字节码:Java源代码经编译后生成的中间代码(.class文件),不是机器码,而是针对JVM设计的指令集。

    好处:

    • 平台无关性 :一次编译,可在任何有JVM的设备上运行;
    • 安全性高 :JVM可对字节码进行安全检查;
    • 执行效率较高 :相比纯解释型语言,字节码更接近机器码,可通过即时编译优化性能。

第二章 Java语言开发环境#

  1. JDK环境的配置

    1. 下载安装JDK :从Oracle官网或OpenJDK发行版下载适合操作系统的JDK安装包并安装。
    2. 设置环境变量
      • JAVA_HOME :指向JDK的安装目录,例如 C:\Program Files\Java\jdk-17
      • PATH :将 %JAVA_HOME%\bin(Windows)或 \$JAVA_HOME/bin(Linux/macOS)添加到系统路径,以便在命令行中使用 javajavac 等命令。
    3. 验证安装 :打开终端或命令行,输入 java -versionjavac -version,查看是否显示正确的版本信息。
  2. Path和ClassPath的作用

    • Path :是操作系统级别的环境变量,用于告诉系统在哪些目录中查找可执行命令(如 javajavac)。配置了 Path 后,可以在任意路径下运行 Java 工具。
    • ClassPath :是 Java 运行环境用来查找用户定义的类(.class 文件)的路径。它告诉 JVM 在哪里寻找要加载的类文件,可以是当前目录、JAR 包或指定的文件夹。可通过 cpCLASSPATH 环境变量设置。
  3. Java应用程序主方法的特点及其作用

    • 方法签名固定 :必须为 public static void main(String[] args)
      • public:确保JVM可以访问该方法。
      • static:无需创建对象即可调用。
      • void:主方法没有返回值。
      • String[] args:用于接收运行时传入的参数。
    • 作用
      • 是 Java 程序执行的起点。
      • 可以通过命令行传递参数(如 java MyApp arg1 arg2),供程序使用。

    每个可独立运行的 Java 类都必须包含一个主方法。

第三章 Java语言基础#

  1. 基本数据类型有哪些?

    1. 整型
      • byte:1 字节(-128 ~ 127)
      • short:2 字节
      • int:4 字节(默认)
      • long:8 字节(需加 L,如 100L
    2. 浮点型
      • float:4 字节(需加 F,如 3.14F
      • double:8 字节(默认)
    3. 字符型
      • char:2 字节(表示 Unicode 字符,如 'A'
    4. 布尔型
      • boolean:仅能存 truefalse(大小由 JVM 决定)
  2. 什么是引用数据类型?

    引用数据类型 是指在 Java 中,变量存储的是对象(或数组)的引用地址,而不是实际的数据值。

    特点:

    • 引用变量指向堆内存中对象的实际位置。
    • 多个引用变量可以指向同一个对象。
    • 操作引用类型时,实际上是通过引用来操作对象。
  3. Java 标识符的命名规则是什么?

    1. 只能包含字母、数字、下划线(_)和美元符号($)
    2. 不能以数字开头 。例如:1name 是非法的。
    3. 不能是 Java 的关键字或保留字 。如 intclassif 等。
    4. 区分大小写ageAge 是两个不同的标识符。
    5. 没有长度限制 ,但应保持简洁有意义。
  4. Java语言是如何声明常量?

    通过 final 关键字来声明,表示其值在整个程序运行期间不能被修改。

  5. 如何将字符串数据类型转换为数值型数据?如何将数值型数据转换为字符串类型?

    转换方向方法示例
    String → intInteger.parseInt(str)
    String → doubleDouble.parseDouble(str)
    int → StringString.valueOf(num)num + ""

第四章 流程控制#

  1. Java中的三种注释方式

    注释类型符号用途
    单行注释//注释一行内容
    多行注释/* ... */注释多行内容
    文档注释/** ... */生成API文档,通常用于类、方法、变量上方
  2. break和continue的含义和区别

    特点breakcontinue
    作用立即终止整个循环跳过当前循环体,进入下一轮
    执行后继续执行循环之后的代码开始下一次循环
    常见用途提前退出循环或匹配到结果时跳过某些不需要处理的情况

第五章 数组与字符串#

  1. 数组的基本概念

    数组(Array) 是一种 有序、固定长度 的数据结构,用于存储 相同类型 的多个数据项。数组中的每个数据项称为一个 元素 ,通过 索引(下标) 来访问。

  2. Java语言的栈内存和堆内存各自的特点。

    特性栈内存(Stack)堆内存(Heap)
    存储内容基本类型变量、对象引用对象实例(包括数组)
    生命周期方法调用开始 → 方法结束对象不再被引用时被 GC 回收
    访问速度较慢
    是否共享线程私有所有线程共享
    内存管理方式自动分配和释放由垃圾回收机制自动管理
  3. 什么是引用变量?

    引用变量 是一种用于指向(引用)堆内存中对象 的变量。它并不直接存储对象本身,而是存储该对象在堆内存中的地址。

  4. String和StringBuffer的区别

    类型是否可变说明
    String❌ 不可变每次对字符串做修改都会生成新的对象,原对象不变。
    StringBuffer✅ 可变在原有对象基础上进行修改,不会产生新对象。
  5. “==”和equals有什么区别?

    比较方式基本类型引用类型(默认)引用类型(重写后,如 String)
    ==比较值比较引用地址比较引用地址
    equals无(仅用于对象)比较引用地址(默认)比较内容(常用方式)

第六章 类与对象#

  1. 面向对象程序设计的基本思想是什么?什么是类?什么是对象?类和对象有怎样的关系?

    基本思想:将现实世界中的事物抽象为“对象” ,通过封装、继承、多态等机制,使程序更贴近人类的思维方式,提高代码的可重用性、可维护性和扩展性。

    什么是类:对一类具有相同特征和行为的对象的模板或蓝图

    什么是对象:类的一个具体实例,是一个真实存在的个体

    类与对象的关系:

    比较项类(Class)对象(Object)
    类型抽象的概念模板具体的实例
    存在形式只有一个模板可以有多个实例
    关系类是对象的类型对象是类的实例化结果
  2. 成员变量与局部变量有哪些区别?

    特征成员变量局部变量
    定义位置类中、方法外方法或代码块内
    生命周期对象存在即存在方法调用期间存在
    访问权限可设置访问修饰符不可设置访问修饰符
    默认值无(必须显式赋值)
    内存位置堆内存栈内存
    是否可以重名可以,优先访问局部变量
  3. 各种类型的默认初始值。

    数据类型默认初始值示例(成员变量)
    byte0byte b; // 0
    short0short s; // 0
    int0int i; // 0
    long0Llong l; // 0L
    float0.0ffloat f; // 0.0f
    double0.0ddouble d; // 0.0d
    char\u0000(空字符)char c; // '\u0000'
    booleanfalseboolean flag; // false
    引用类型(如**String**、数组、对象等)nullString str; // null

    成员变量有默认初始值,引用类型默认为 null;局部变量没有默认值,必须手动初始化后才能使用。

第七章 Java语言类的特征#

  1. 私有成员(private)、公共成员(public)、保护成员(protected)、缺省访问控制符各自的访问权限是什么?

    访问修饰符同一个类中同一个包中子类(不同包)其他包
    private
    缺省(默认)
    protected✅(通过继承)
    public
  2. 什么是方法的重载,即方法的重载条件是什么?会判断哪些是合法的重载形式。

    方法重载 是指在同一个类中,允许存在多个同名方法 ,但它们的 参数列表不同(参数个数、参数类型或参数顺序不同) 。

    判断是否为合法重载的关键点:#

    判断项是否影响重载
    方法名必须相同
    参数个数✅ 影响
    参数类型✅ 影响
    参数顺序✅ 影响
    返回值类型❌ 不影响
    访问修饰符❌ 不影响
    异常声明❌ 不影响
  3. 什么是构造方法?构造方法有哪些特征?何时被调用?什么是默认构造方法?何时被调用

    构造方法是一种特殊的方法,用于在创建对象时对对象进行初始化操作。

    构造方法的特征

    特征说明
    方法名必须与类名相同如:Person()
    没有返回值类型连**void**也不能写
    可以重载一个类中可以有多个构造方法(参数不同)
    不能被继承、不能被覆盖(不能**override**)子类可以调用父类构造方法(通过**super()**)
    可以有访问修饰符如**publicprivate**等

    构造方法在使用 new 关键字创建对象时自动调用

    如果一个类没有显式定义任何构造方法 ,Java 编译器会自动为该类生成一个无参构造方法 ,称为默认构造方法

  4. 什么是静态成员(类成员)?什么是实例成员?使用静态成员有什么意义?静态成员的访问格式是什么?main方法为何是public, static的呢

    什么是静态成员(类成员)?什么是实例成员?

    类型静态成员(类成员)实例成员(对象成员)
    定义方式使用**static**关键字修饰不使用**static**
    所属对象属于类本身属于类的每一个具体对象
    内存分配只分配一次,独立于对象每创建一个对象就分配一次
    访问权限可通过类名或对象访问必须通过对象访问

    使用静态成员有什么意义?

    1. 共享数据 :多个对象共享同一个静态变量。
    2. 无需创建对象即可访问 :适合工具类、常量定义等场景。
    3. 节省内存资源 :只存储一份,避免重复占用。
    4. 作为程序入口点 :如 main 方法必须是 public static

    静态成员的访问格式

    • 推荐写法 (清晰明确):类名.静态成员;
    • 也可以用对象访问 (不推荐):对象名.静态成员;

    为什么 main 方法是 public static 的?

    1. public

    • 表示该方法对外公开,JVM 可以从外部访问它。

    2. static

    • 表示这是一个类方法 ,不需要创建对象就可以调用。
    • JVM 在启动时还没有创建任何对象,所以必须通过 static 方法来执行程序入口。

    如果 main 方法不是 static,JVM 就无法在没有对象的情况下调用它,导致程序无法运行。

第八章 继承、抽象类和接口#

  1. 在子类中如何访问父类的成员?用父类的对象(名)访问子类的成员,只限什么情况才行?

    在子类中可以直接访问父类的可访问成员,或通过 super 显式调用;而用父类引用访问子类成员时,只能访问父类中定义的内容 ,若要访问子类特有成员,必须进行 向下转型 。

  2. 什么是方法的覆盖?方法的覆盖与方法的重载有何区别?

    方法重载是在同一个类中方法名相同、参数不同的一组方法;方法覆盖是在子类中对父类方法进行重新实现,用于多态。

  3. 什么是抽象类和抽象方法?抽象类有哪些特征?

    抽象类 是使用 abstract 关键字修饰的类,它不能被实例化(不能用 new 创建对象),通常用于作为其他类的父类。

    抽象类的特征:

    特征说明
    使用**abstract**修饰public abstract class Animal{}
    不能创建对象不能通过**new**实例化
    可以包含抽象方法也可以不包含(即全是具体方法)
    可以包含具体方法和普通类一样,可以有实现的方法
    可以有构造方法用于子类调用(通过**super()**)
    可以有成员变量和成员方法支持各种访问控制符
    支持继承子类必须实现所有抽象方法或本身也是抽象类
    与接口的区别抽象类支持构造方法、成员变量、非抽象方法等
  4. 接口的定义?接口与抽象类有何区别?

    接口 是一种特殊的“抽象类”,它只包含常量和抽象方法 (Java 8 之前),用于定义一组行为规范。从 Java 8 开始,接口支持默认方法和静态方法。

    接口与抽象类的区别

    比较项接口(Interface)抽象类(Abstract Class)
    定义关键字interfaceabstract class
    方法实现可全为抽象(也可有默认/静态方法)可以有具体方法
    成员变量默认**public static final**可以是普通变量
    构造方法❌ 没有构造方法✅ 有构造方法
    继承关系类可以实现多个接口类只能继承一个抽象类
    访问权限方法默认**public**成员可使用各种访问修饰符
    多继承支持✅ 支持❌ 不支持
    设计目的行为规范(“能做什么”)状态 + 行为模板(“是什么”)
    Java版本限制Java 1.0 起Java 1.0 起
  5. Java8以后,接口中增加的static方法和default方法各自的含义、作用和使用?

    默认方法:

    定义:

    默认方法是使用 default 关键字修饰的方法,有方法体 ,提供一个默认实现。 子类可以选择重写或直接使用这个默认实现。

    作用:

    向后兼容 :为已有的接口添加新方法时,不会破坏现有实现类。 共享默认行为 :多个实现类可以共用一套默认逻辑。 支持多继承行为 :一个类可以实现多个接口并继承它们的默认方法。

    静态方法:

    定义:

    接口中的静态方法类似于类的静态方法,可以直接通过接口名调用 ,不能被实现类继承或重写。

    作用:

    封装工具方法 :可以将一些通用的辅助方法放在接口中。 明确归属 :方法属于接口本身,而不是其实现类。 代码组织更清晰 :接口不仅定义行为规范,也可以提供实用方法。

  6. 如何理解Java的多态性?

    Java 的多态性是指在继承关系中,通过方法重写和向上转型,使父类引用可以指向不同子类对象,并在运行时自动调用对应的方法,从而实现“一个接口,多种行为”的机制。

第九章 异常处理#

  1. 什么是异常?按照错误的性质将错误如何分类及其含义?

    异常(Exception) 是指程序在运行过程中发生的、打断正常流程的错误或意外情况。

    按照错误的性质,Java 中的错误主要分为以下三类:

    1. 语法错误(Compile-time Error)
      • 含义:代码不符合 Java 语法规则,在编译阶段就会被发现。
      • 示例:缺少分号、拼写错误、类型不匹配等。
      • 处理方式:必须在编译前修正,否则无法生成字节码。
    2. 运行时错误(Runtime Error)
      • 含义:程序在运行过程中出现的错误,通常由意外情况引起,编译时不会被检测到。
      • 示例:除以零、空指针访问、数组越界等。
      • 处理方式:通过异常处理机制(如 try-catch)捕获和处理。
    3. 逻辑错误(Logical Error)
      • 含义:程序语法正确,也能正常运行,但结果不符合预期。
      • 示例:条件判断写错、变量使用错误等。
      • 处理方式:需通过调试查找并修正逻辑问题。
  2. 简述Java的异常处理机制?

    Java 的异常处理机制是一种结构化、统一的错误处理方式 ,通过 try-catch-finally 和 throws/throw 语句来管理和响应运行时错误。

    核心组成: try 块 :用于包裹可能抛出异常的代码。 catch 块 :捕获并处理 try 块中发生的异常。 finally 块 :无论是否发生异常,都会执行,通常用于释放资源(如关闭文件或网络连接)。 throw :手动抛出一个异常对象。 throws :在方法声明中指明该方法可能抛出的异常,调用者需处理。

  3. 什么是抛出异常和捕获异常?

    • 抛出异常 是产生并传递异常的过程;
    • 捕获异常 是对异常进行处理的过程;

第十一章 泛型和容器#

  1. 泛型的实质是什么?使用泛型有什么好处?

    泛型的实质 是参数化类型,即在定义类、接口或方法时,不指定具体的类型,而是使用一个类型参数(如 T),在使用时再指定具体类型。

    使用泛型的好处:

    1. 类型安全 :编译器在编译时进行类型检查,避免运行时因类型不匹配导致错误。
    2. 代码复用 :一套逻辑可以适用于多种数据类型,减少重复代码。
    3. 去除强制类型转换 :使用泛型后,集合或类中存储的对象无需再手动强转为目标类型。
    4. 提高可读性和维护性 :类型信息明确,使代码更清晰易懂,易于维护。
  2. 使用通配符的目的?

    使用通配符(?)的目的 是为了增强泛型的灵活性,特别是在不确定具体类型参数 或需要处理多种类型参数的场景下。

  3. 什么是容器类?Java容器框架主要包含哪两个接口?

    容器类(Container Class) 是用于存储和管理其他对象 的类,本质上是用来组织数据的集合。在 Java 中,容器类主要指的是 Java 集合框架(Java Collection Framework) 中的类。

    Java 容器框架 的核心接口是:java.util.Collection java.util.Map

  4. 链表类和数组列表类均为List的实现类,各自有什么特点和适用于哪类问题?

    特性ArrayListLinkedList
    底层结构动态数组双向链表
    访问速度快(O(1))慢(O(n))
    插入/删除速度慢(O(n))快(O(1))
    内存占用较小较大(节点开销)
    适用场景多查询、少增删多增删、实现数据结构
  5. 什么叫做遍历(迭代)?

    遍历 就是“一个一个地访问集合中的元素”,是集合操作中最基本、最常用的操作之一。不同的遍历方式适用于不同的场景,选择合适的方式可以提升代码可读性和性能。

  6. 哈希集合类与树集合类主要有什么区别?分别适用于哪类问题?

    特性HashSetTreeSet
    底层结构哈希表红黑树
    元素顺序无序(插入顺序不保留)有序(默认升序)
    插入/查找效率O(1)O(log n)
    是否允许 null是(仅一个)
    是否支持排序
    主要用途快速去重、高效查找有序集合、范围查询、排序需求
  7. 哈希映射和树映射主要有些什么区别?分别适用于哪类问题?

    特性HashMapTreeMap
    底层结构哈希表红黑树
    键的顺序无序按键排序(升序)
    插入/查找效率O(1)O(log n)
    是否允许 null 键是(仅一个)
    是否支持排序
    主要用途快速查找、缓存、去重排序输出、区间查询、有序访问

第十二章 内部类、匿名内部类和函数式接口#

  1. 内部类概念、定义及使用?内部类的主要作用是什么?

    概念:指定义在另一个类内部的类。它是 Java 中面向对象特性的一部分,用于更灵活地组织代码结构。

    定义:

    public class OuterClass {
    // 外部类成员
    // 内部类定义
    public class InnerClass {
    // 内部类成员
    }
    }

    使用:

    public class Outer {
    private String msg = "Hello Inner Class";
    public class Inner {
    void print() {
    System.out.println(msg); // 可以访问外部类的成员
    }
    }
    public static void main(String[] args) {
    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();
    inner.print(); // 输出:Hello Inner Class
    }
    }

    作用:

    1. 实现更好的封装性:
      • 内部类可以访问外部类的所有成员(包括私有成员),适合用于逻辑紧密相关的类之间。
    2. 提高代码可读性和维护性:
      • 将逻辑相关的类组织在一起,使结构更清晰、模块化更强。
    3. 实现多重继承的效果:
      • 一个类可以继承一个类并同时拥有多个内部类实现不同的接口,增强灵活性。
    4. 简化代码,特别是匿名内部类:
      • 常用于监听器、线程任务等场景,例如图形界面或多线程编程中简化回调逻辑。
  2. 匿名内部类的概念、定义及使用。

    概念:没有显式名称的内部类,通常在创建对象的同时直接定义类并实例化。 它适用于只需要使用一次的类,比如事件监听、线程任务等。

    定义:

    new 父类构造器参数或接口() {
    // 类体(重写方法、定义变量等)
    };

    使用:

    // 定义一个接口
    interface OnClickListener {
    void onClick();
    }
    public class Button {
    public void setOnClickListener(OnClickListener listener) {
    listener.onClick();
    }
    public static void main(String[] args) {
    Button button = new Button();
    // 使用匿名内部类实现接口
    button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick() {
    System.out.println("按钮被点击了!");
    }
    });
    }
    }
  3. 什么是函数式接口?什么是注解?

    函数式接口:只有一个抽象方法 的接口,可以有默认方法和静态方法。

    注解:注解是一种元数据(Metadata) ,它为程序元素(如类、方法、变量等)提供附加信息,并不会直接影响程序逻辑,但可以被编译器、框架或工具读取和处理。

期末·Java 程序设计基础
https://blog.snowy.moe/posts/2874/
作者
Muika
发布于
2026-01-19
许可协议
CC BY-NC-SA 4.0