Java常见代码大全:从基础语法到设计模式的实用指南

一、Java基础语法

(一)变量与数据类型

1. 基本数据类型

Java是一种强类型语言,每种数据类型都有明确的定义和范围。基本数据类型是Java中最基础的部分,它们是直接存储在栈内存中的简单数据类型,具有固定的大小和格式。

  • 整数类型

    • byte:占用1个字节(8位),范围是-128127。适用于存储占用空间较小的整数。
      byte b = 10;
      
    • short:占用2个字节(16位),范围是-3276832767。比byte范围大,但仍然比int小。
      short s = 1000;
      
    • int:占用4个字节(32位),范围是-2^312^31-1,即-21474836482147483647。这是最常用的整数类型。
      int i = 100000;
      
    • long:占用8个字节(64位),范围是-2^632^63-1,即-92233720368547758089223372036854775807。当需要存储较大的整数时使用。
      long l = 10000000000L; // 注意:以L结尾表示是long类型
      
  • 浮点类型

    • float:占用4个字节(32位),表示单精度浮点数。它的精度较低,但占用空间小。
      float f = 3.14f; // 注意:以f结尾表示是float类型
      
    • double:占用8个字节(64位),表示双精度浮点数。它的精度高,是浮点数的默认类型。
      double d = 3.141592653589793;
      
  • 字符类型

    • char:占用2个字节(16位),表示一个Unicode字符。它的范围是'\u0000'(即0)到'\uffff'(即65535)。
      char c = 'A';
      char c1 = '\u0041'; // Unicode表示法,等同于'A'
      
  • 布尔类型

    • boolean:只有两个值:truefalse。它通常用于逻辑判断。
      boolean flag = true;
      

2. 包装类

Java为每种基本数据类型都提供了一个对应的包装类(Wrapper Class),这些包装类是类,而不是原始数据类型。包装类允许我们将基本数据类型当作对象来处理。

  • 包装类的作用

    • 自动装箱:将基本数据类型自动转换为对应的包装类。例如:
      Integer i = 10; // 自动装箱,将int转换为Integer
      
    • 自动拆箱:将包装类自动转换为对应的基本数据类型。例如:
      int j = i; // 自动拆箱,将Integer转换为int
      
  • 包装类的使用场景

    • 当需要将基本数据类型作为对象存储在集合中时,必须使用包装类。例如:
      List<Integer> list = new ArrayList<>();
      list.add(10); // 自动装箱
      int num = list.get(0); // 自动拆箱
      
  • 包装类与基本数据类型的区别

    • 包装类是对象,而基本数据类型是原始类型。包装类可以为null,而基本数据类型不能为null
    • 包装类在性能上比基本数据类型稍差,因为它们需要额外的内存空间来存储对象的元数据。

3. 类型转换

在Java中,类型转换分为自动类型转换和强制类型转换。

  • 自动类型转换

    • 当从较小范围的类型向较大范围的类型转换时,Java会自动进行类型转换。例如:
      int i = 10;
      long l = i; // 自动将int转换为long
      double d = l; // 自动将long转换为double
      
  • 强制类型转换

    • 当需要从较大范围的类型向较小范围的类型转换时,必须使用强制类型转换。强制类型转换可能会导致数据丢失。例如:
      double d = 3.141592653589793;
      int i = (int) d; // 强制将double转换为int,小数部分会被截断
      

4. 常见代码示例

public class DataTypeExample {
    public static void main(String[] args) {
        // 基本数据类型
        byte b = 10;
        short s = 1000;
        int i = 100000;
        long l = 10000000000L;

        float f = 3.14f;
        double d = 3.141592653589793;

        char c = 'A';
        boolean flag = true;

        // 包装类
        Integer integer = 10; // 自动装箱
        int num = integer; // 自动拆箱

        // 类型转换
        long longValue = i; // 自动类型转换
        int intValue = (int) l; // 强制类型转换

        // 输出
        System.out.println("byte: " + b);
        System.out.println("short: " + s);
        System.out.println("int: " + i);
        System.out.println("long: " + l);
        System.out.println("float: " + f);
        System.out.println("double: " + d);
        System.out.println("char: " + c);
        System.out.println("boolean: " + flag);
        System.out.println("包装类Integer: " + integer);
        System.out.println("自动拆箱后的int: " + num);
        System.out.println("自动类型转换后的long: " + longValue);
        System.out.println("强制类型转换后的int: " + intValue);
    }
}

(二)运算符

Java提供了多种运算符,用于执行各种数学和逻辑运算。运算符是Java编程中不可或缺的一部分,掌握它们的使用方法对于编写高效的代码至关重要。

1. 算术运算符

算术运算符用于执行基本的数学运算,如加法、减法、乘法、除法和取模。

  • 加法运算符+

    • 用于两个数值相加。
      int a = 10;
      int b = 20;
      int sum = a + b; // 结果为30
      
  • 减法运算符-

    • 用于两个数值相减。
      int a = 20;
      int b = 10;
      int difference = a - b; // 结果为10
      
  • 乘法运算符*

    • 用于两个数值相乘。
      int a = 10;
      int b = 20;
      int product = a * b; // 结果为200
      
  • 除法运算符/

    • 用于两个数值相除。如果两个操作数都是整数,则结果也是整数;如果有一个操作数是浮点数,则结果是浮点数。
      int a = 20;
      int b = 10;
      int quotient = a / b; // 结果为2
      
      double c = 20.0;
      double d = 10.0;
      double quotientDouble = c / d; // 结果为2.0
      
  • 取模运算符%

    • 用于计算两个数值相除的余数。
      
      int a = 20;
      int b = 3;
      int remainder = a % b; // 结果为2
      

2. 关系运算符

关系运算符用于比较两个数值的大小,结果是一个布尔值(truefalse)。

  • 等于==

    • 用于比较两个值是否相等。
      int a = 10;
      int b = 20;
      boolean isEqual = a == b; // 结果为false
      
  • 不等于!=

    • 用于比较两个值是否不相等。
      int a = 10;
      int b = 20;
      boolean isNotEqual = a != b; // 结果为true
      
  • 大于>

    • 用于比较一个值是否大于另一个值。
      int a = 20;
      int b = 10;
      boolean isGreaterThan = a > b; // 结果为true
      
  • 小于<

    • 用于比较一个值是否小于另一个值。
      int a = 10;
      int b = 20;
      boolean isLessThan = a < b; // 结果为true
      
  • 大于等于>=

    • 用于比较一个值是否大于或等于另一个值。
      int a = 20;
      int b = 10;
      boolean isGreaterThanOrEqual = a >= b; // 结果为true
      
  • 小于等于<=

    • 用于比较一个值是否小于或等于另一个值。
      int a = 10;
      int b = 20;
      boolean isLessThanOrEqual = a <= b; // 结果为true
      

3. 逻辑运算符

逻辑运算符用于组合多个条件,结果是一个布尔值(truefalse)。

  • 逻辑与&&

    • 用于表示“并且”的关系。只有当两个条件都为true时,结果才为true
      int a = 10;
      int b = 20;
      boolean result = (a > 5) && (b > 15); // 结果为true
      
  • 逻辑或||

    • 用于表示“或者”的关系。只要有一个条件为true,结果就为true
      int a = 10;
      int b = 20;
      boolean result = (a > 15) || (b > 15); // 结果为true
      
  • 逻辑非!

    • 用于对一个布尔值取反。如果原值为true,则结果为false;如果原值为false,则结果为true
      boolean flag = true;
      boolean result = !flag; // 结果为false
      

4. 赋值运算符

赋值运算符用于将一个值赋给一个变量。

  • 简单赋值=

    • 用于将一个值赋给一个变量。
      int a = 10;
      
  • 复合赋值运算符

    • 加法赋值+=:将变量与另一个值相加后赋值给变量。

      int a = 10;
      a += 5; // 等同于a = a + 5,结果a为15
      
    • 减法赋值-=:将变量与另一个值相减后赋值给变量。

      int a = 10;
      a -= 5; // 等同于a = a - 5,结果a为5
      
    • 乘法赋值*=:将变量与另一个值相乘后赋值给变量。

      int a = 10;
      a *= 5; // 等同于a = a * 5,结果a为50
      
    • 除法赋值/=:将变量与另一个值相除后赋值给变量。

      int a = 10;
      a /= 5; // 等同于a = a / 5,结果a为2
      
    • 取模赋值%=:将变量与另一个值取模后赋值给变量。

      int a = 10;
      a %= 3; // 等同于a = a % 3,结果a为1
      

5. 常见代码示例

public class OperatorExample {
    public static void main(String[] args) {
        // 算术运算符
        int a = 10;
        int b = 3;
        int sum = a + b; // 加法
        int difference = a - b; // 减法
        int product = a * b; // 乘法
        int quotient = a / b; // 除法
        int remainder = a % b; // 取模

        // 关系运算符
        boolean isEqual = a == b; // 等于
        boolean isNotEqual = a != b; // 不等于
        boolean isGreaterThan = a > b; // 大于
        boolean isLessThan = a < b; // 小于
        boolean isGreaterThanOrEqual = a >= b; // 大于等于
        boolean isLessThanOrEqual = a <= b; // 小于等于

        // 逻辑运算符
        boolean flag1 = true;
        boolean flag2 = false;
        boolean andResult = flag1 && flag2; // 逻辑与
        boolean orResult = flag1 || flag2; // 逻辑或
        boolean notResult = !flag1; // 逻辑非

        // 赋值运算符
        int x = 10;
        x += 5; // 加法赋值
        x -= 3; // 减法赋值
        x *= 2; // 乘法赋值
        x /= 4; // 除法赋值
        x %= 3; // 取模赋值

        // 输出结果
        System.out.println("加法结果: " + sum);
        System.out.println("减法结果: " + difference);
        System.out.println("乘法结果: " + product);
        System.out.println("除法结果: " + quotient);
        System.out.println("取模结果: " + remainder);
        System.out.println("等于: " + isEqual);
        System.out.println("不等于: " + isNotEqual);
        System.out.println("大于: " + isGreaterThan);
        System.out.println("小于: " + isLessThan);
        System.out.println("大于等于: " + isGreaterThanOrEqual);
        System.out.println("小于等于: " + isLessThanOrEqual);
        System.out.println("逻辑与结果: " + andResult);
        System.out.println("逻辑或结果: " + orResult);
        System.out.println("逻辑非结果: " + notResult);
        System.out.println("加法赋值后的x: " + x);
        System.out.println("减法赋值后的x: " + x);
        System.out.println("乘法赋值后的x: " + x);
        System.out.println("除法赋值后的x: " + x);
        System.out.println("取模赋值后的x: " + x);
    }
}

(三)控制流程

控制流程语句用于控制程序的执行顺序。Java提供了多种控制流程语句,包括条件语句和循环语句。

1. 条件语句

条件语句用于根据条件的真假来决定程序的执行路径。

  • if-else语句

    • if语句用于判断一个条件是否为true。如果条件为true,则执行if块中的代码;如果条件为false,则可以执行else块中的代码。
      int a = 10;
      if (a > 5) {
          System.out.println("a大于5");
      } else {
          System.out.println("a不大于5");
      }
      
  • if-else if-else语句

    • 当需要判断多个条件时,可以使用if-else if-else语句。
      int score = 85;
      if (score >= 90) {
          System.out.println("优秀");
      } else if (score >= 80) {
          System.out.println("良好");
      } else if (score >= 60) {
          System.out.println("及格");
      } else {
          System.out.println("不及格");
      }
      
  • switch-case语句

    • switch-case语句用于根据一个变量的值来选择执行不同的代码块。它通常用于替代多个if-else语句。
      int month = 3;
      switch (month) {
          case 1:
              System.out.println("一月");
              break;
          case 2:
              System.out.println("二月");
              break;
          case 3:
              System.out.println("三月");
              break;
          // 其他月份...
          default:
              System.out.println("无效的月份");
              break;
      }
      

2. 循环语句

循环语句用于重复执行一段代码,直到满足某个条件为止。

  • for循环

    • for循环是最常用的循环语句之一。它通常用于已知循环次数的场景。
      for (int i = 0; i < 5; i++) {
          System.out.println("循环次数: " + i);
      }
      
  • while循环

    • while循环用于在条件为true时重复执行一段代码。它在循环开始前先判断条件。
      int i = 0;
      while (i < 5) {
          System.out.println("循环次数: " + i);
          i++;
      }
      
  • do-while循环

    • do-while循环与while循环类似,但它在循环开始后先执行一次代码,然后再判断条件。因此,do-while循环至少会执行一次。
      int i = 0;
      do {
          System.out.println("循环次数: " + i);
          i++;
      } while (i < 5);
      

3. 跳转语句

跳转语句用于在循环中改变程序的执行流程。

  • break语句

    • break语句用于终止循环或switch-case语句。
      for (int i = 0; i < 10; i++) {
          if (i == 5) {
              break; // 终止循环
          }
          System.out.println("循环次数: " + i);
      }
      
  • continue语句

    • continue语句用于跳过当前循环的剩余部分,并继续执行下一次循环。
      for (int i = 0; i < 10; i++) {
          if (i % 2 == 0) {
              continue; // 跳过偶数
          }
          System.out.println("循环次数: " + i);
      }
      

4. 常见代码示例

public class ControlFlowExample {
    public static void main(String[] args) {
        // if-else语句
        int a = 10;
        if (a > 5) {
            System.out.println("a大于5");
        } else {
            System.out.println("a不大于5");
        }

        // if-else if-else语句
        int score = 85;
        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 80) {
            System.out.println("良好");
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }

        // switch-case语句
        int month = 3;
        switch (month) {
            case 1:
                System.out.println("一月");
                break;
            case 2:
                System.out.println("二月");
                break;
            case 3:
                System.out.println("三月");
                break;
            // 其他月份...
            default:
                System.out.println("无效的月份");
                break;
        }

        // for循环
        for (int i = 0; i < 5; i++) {
            System.out.println("for循环次数: " + i);
        }

        // while循环
        int j = 0;
        while (j < 5) {
            System.out.println("while循环次数: " + j);
            j++;
        }

        // do-while循环
        int k = 0;
        do {
            System.out.println("do-while循环次数: " + k);
            k++;
        } while (k < 5);

        // break语句
        for (int i = 0; i < 10; i++) {
            if (i == 5) {
                break; // 终止循环
            }
            System.out.println("break循环次数: " + i);
        }

        // continue语句
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                continue; // 跳过偶数
            }
            System.out.println("continue循环次数: " + i);
        }
    }
}

(四)数组

数组是一种可以存储多个相同类型数据的容器。在Java中,数组的大小是固定的,一旦创建后不能改变。

1. 数组的声明与初始化

  • 声明数组

    • 声明数组时,需要指定数组的类型和名称。
      int[] array; // 声明一个整型数组
      
  • 初始化数组

    • 静态初始化:在声明数组时直接指定数组的元素。

      int[] array = {1, 2, 3, 4, 5};
      
    • 动态初始化:指定数组的大小,然后逐个赋值。

      int[] array = new int[5]; // 创建一个长度为5的数组
      array[0] = 1;
      array[1] = 2;
      array[2] = 3;
      array[3] = 4;
      array[4] = 5;
      

2. 数组的遍历

  • 使用for循环遍历数组

    int[] array = {1, 2, 3, 4, 5};
    for (int i = 0; i < array.length; i++) {
        System.out.println(array[i]);
    }
    
  • 使用for-each循环遍历数组

    int[] array = {1, 2, 3, 4, 5};
    for (int num : array) {
        System.out.println(num);
    }
    

3. 多维数组

多维数组是数组的数组,可以用来存储更复杂的数据结构。

  • 二维数组

    • 静态初始化

      int[][] matrix = {
          {1, 2, 3},
          {4, 5, 6},
          {7, 8, 9}
      };
      
    • 动态初始化

      int[][] matrix = new int[3][3];
      matrix[0][0] = 1;
      matrix[0][1] = 2;
      matrix[0][2] = 3;
      matrix[1][0] = 4;
      matrix[1][1] = 5;
      matrix[1][2] = 6;
      matrix[2][0] = 7;
      matrix[2][1] = 8;
      matrix[2][2] = 9;
      
  • 遍历二维数组

    int[][] matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            System.out.print(matrix[i][j] + " ");
        }
        System.out.println();
    }
    

4. 常见代码示例

public class ArrayExample {
    public static void main(String[] args) {
        // 一维数组
        int[] array = {1, 2, 3, 4, 5};
        System.out.println("一维数组的元素:");
        for (int num : array) {
            System.out.println(num);
        }

        // 二维数组
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        System.out.println("二维数组的元素:");
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }

        // 动态初始化一维数组
        int[] dynamicArray = new int[5];
        for (int i = 0; i < dynamicArray.length; i++) {
            dynamicArray[i] = i + 1;
        }
        System.out.println("动态初始化的一维数组:");
        for (int num : dynamicArray) {
            System.out.println(num);
        }

        // 动态初始化二维数组
        int[][] dynamicMatrix = new int[3][3];
        for (int i = 0; i < dynamicMatrix.length; i++) {
            for (int j = 0; j < dynamicMatrix[i].length; j++) {
                dynamicMatrix[i][j] = i * 3 + j + 1;
            }
        }
        System.out.println("动态初始化的二维数组:");
        for (int i = 0; i < dynamicMatrix.length; i++) {
            for (int j = 0; j < dynamicMatrix[i].length; j++) {
                System.out.print(dynamicMatrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}

(五)方法

方法是一段可以重复使用的代码块,用于完成特定的功能。在Java中,方法是类的一部分,通过方法可以实现代码的封装和复用。

1. 方法的定义

方法的定义包括方法的返回类型、方法名、参数列表和方法体。

  • 返回类型:方法执行完成后返回的值的类型。如果方法不返回任何值,则返回类型为void
  • 方法名:方法的名称,用于标识方法。
  • 参数列表:方法的输入参数,可以有多个参数,也可以没有参数。
  • 方法体:方法的具体实现部分,包含一系列的语句。
public class MethodExample {
    // 定义一个无参方法
    public void sayHello() {
        System.out.println("Hello, World!");
    }

    // 定义一个有参方法
    public int add(int a, int b) {
        return a + b;
    }

    // 定义一个带返回值的方法
    public String getGreeting(String name) {
        return "Hello, " + name + "!";
    }

    public static void main(String[] args) {
        MethodExample example = new MethodExample();

        // 调用无参方法
        example.sayHello();

        // 调用有参方法
        int result = example.add(10, 20);
        System.out.println("加法结果: " + result);

        // 调用带返回值的方法
        String greeting = example.getGreeting("Kimi");
        System.out.println(greeting);
    }
}

2. 方法的重载

方法重载是指在同一个类中,允许定义多个同名的方法,但这些方法的参数列表必须不同(参数的类型、个数或顺序不同)。方法重载允许我们根据不同的输入参数调用不同的方法实现。

public class MethodOverloadingExample {
    // 方法重载:无参数
    public void print() {
        System.out.println("无参数的方法");
    }

    // 方法重载:一个参数
    public void print(String message) {
        System.out.println("字符串参数的方法: " + message);
    }

    // 方法重载:两个参数
    public void print(String message, int num) {
        System.out.println("字符串和整数参数的方法: " + message + ", " + num);
    }

    public static void main(String[] args) {
        MethodOverloadingExample example = new MethodOverloadingExample();

        // 调用重载方法
        example.print(); // 调用无参数的方法
        example.print("Hello"); // 调用一个参数的方法
        example.print("Hello", 123); // 调用两个参数的方法
    }
}

3. 方法的递归

递归是一种方法调用自身的技术。递归通常用于解决可以分解为相同问题的子问题的场景。

public class RecursiveExample {
    // 定义一个递归方法:计算阶乘
    public int factorial(int n) {
        if (n == 1) {
            return 1; // 递归终止条件
        } else {
            return n * factorial(n - 1); // 递归调用
        }
    }

    public static void main(String[] args) {
        RecursiveExample example = new RecursiveExample();

        // 调用递归方法
        int result = example.factorial(5);
        System.out.println("5的阶乘是: " + result);
    }
}

(六)类与对象

类是Java中最重要的概念之一,它是对象的模板,定义了对象的结构和行为。对象是类的实例,是类的具体实现。

1. 类的定义

类的定义包括类的名称、成员变量和成员方法。

  • 成员变量:类的属性,用于存储对象的状态。
  • 成员方法:类的行为,用于定义对象的操作。
public class Person {
    // 成员变量
    private String name;
    private int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 成员方法:获取姓名
    public String getName() {
        return name;
    }

    // 成员方法:设置姓名
    public void setName(String name) {
        this.name = name;
    }

    // 成员方法:获取年龄
    public int getAge() {
        return age;
    }

    // 成员方法:设置年龄
    public void setAge(int age) {
        this.age = age;
    }

    // 成员方法:打印个人信息
    public void printInfo() {
        System.out.println("姓名: " + name + ", 年龄: " + age);
    }
}

2. 对象的创建与使用

对象是类的实例,可以通过new关键字创建对象。

public class ObjectExample {
    public static void main(String[] args) {
        // 创建Person对象
        Person person = new Person("Kimi", 25);

        // 调用对象的方法
        person.printInfo(); // 输出:姓名: Kimi, 年龄: 25

        // 修改对象的属性
        person.setName("Alice");
        person.setAge(30);

        // 再次调用方法
        person.printInfo(); // 输出:姓名: Alice, 年龄: 30
    }
}

3. this关键字

this关键字用于引用类的当前实例。它通常用于区分同名的成员变量和局部变量。

public class ThisExample {
    private int num;

    public ThisExample(int num) {
        this.num = num; // 使用this区分成员变量和局部变量
    }

    public void printNum() {
        System.out.println("num的值是: " + this.num); // 使用this引用成员变量
    }

    public static void main(String[] args) {
        ThisExample example = new ThisExample(100);
        example.printNum(); // 输出:num的值是: 100
    }
}

4. 构造方法

构造方法是类的一种特殊方法,用于在创建对象时初始化对象。构造方法的名称必须与类名相同,并且没有返回值。

  • 无参构造方法

    • 如果没有显式定义构造方法,Java会提供一个默认的无参构造方法。
      public class Person {
          private String name;
          private int age;
      
          // 无参构造方法
          public Person() {
          }
      
          // 有参构造方法
          public Person(String name, int age) {
              this.name = name;
              this.age = age;
          }
      }
      
  • 有参构造方法

    • 有参构造方法用于在创建对象时直接初始化对象的属性。
      Person person = new Person("Kimi", 25);
      

5. 常见代码示例

public class ClassAndObjectExample {
    // 定义一个类
    public static class Person {
        private String name;
        private int age;

        // 无参构造方法
        public Person() {
        }

        // 有参构造方法
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        // 成员方法:获取姓名
        public String getName() {
            return name;
        }

        // 成员方法:设置姓名
        public void setName(String name) {
            this.name = name;
        }

        // 成员方法:获取年龄
        public int getAge() {
            return age;
        }

        // 成员方法:设置年龄
        public void setAge(int age) {
            this.age = age;
        }

        // 成员方法:打印个人信息
        public void printInfo() {
            System.out.println("姓名: " + name + ", 年龄: " + age);
        }
    }

    public static void main(String[] args) {
        // 创建对象

        Person person1 = new Person(); // 使用无参构造方法
        person1.setName("Kimi");
        person1.setAge(25);
        person1.printInfo(); // 输出:姓名: Kimi, 年龄: 25

        Person person2 = new Person("Alice", 30); // 使用有参构造方法
        person2.printInfo(); // 输出:姓名: Alice, 年龄: 30
    }
}

(七)继承

继承是面向对象编程的核心概念之一,它允许一个类继承另一个类的属性和方法。通过继承,可以实现代码的复用和扩展。

1. 继承的语法

在Java中,继承使用extends关键字来实现。子类继承父类后,可以访问父类的非私有成员变量和方法。

public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + "正在吃东西");
    }
}

public class Dog extends Animal {
    public Dog(String name) {
        super(name); // 调用父类的构造方法
    }

    public void bark() {
        System.out.println(name + "正在叫");
    }
}

2. 方法的重写

方法重写是指子类可以重新定义父类的方法。重写的方法必须与父类的方法具有相同的方法名、参数列表和返回类型。

public class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

3. super关键字

super关键字用于引用父类的成员变量和方法。它通常用于调用父类的构造方法或访问父类的成员变量。

public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public class Dog extends Animal {
    private String breed;

    public Dog(String name, String breed) {
        super(name); // 调用父类的构造方法
        this.breed = breed;
    }

    public void printInfo() {
        System.out.println("名字: " + super.getName() + ", 品种: " + breed);
    }
}

4. 常见代码示例

public class InheritanceExample {
    // 定义父类
    public static class Animal {
        private String name;

        public Animal(String name) {
            this.name = name;
        }

        public void eat() {
            System.out.println(name + "正在吃东西");
        }

        public void makeSound() {
            System.out.println(name + "发出声音");
        }
    }

    // 定义子类
    public static class Dog extends Animal {
        private String breed;

        public Dog(String name, String breed) {
            super(name); // 调用父类的构造方法
            this.breed = breed;
        }

        @Override
        public void makeSound() {
            System.out.println(name + "汪汪叫");
        }

        public void printInfo() {
            System.out.println("名字: " + super.getName() + ", 品种: " + breed);
        }
    }

    public static void main(String[] args) {
        // 创建父类对象
        Animal animal = new Animal("动物");
        animal.eat(); // 输出:动物正在吃东西
        animal.makeSound(); // 输出:动物发出声音

        // 创建子类对象
        Dog dog = new Dog("小狗", "哈士奇");
        dog.eat(); // 输出:小狗正在吃东西(继承自父类)
        dog.makeSound(); // 输出:小狗汪汪叫(重写的方法)
        dog.printInfo(); // 输出:名字: 小狗, 品种: 哈士奇
    }
}

(八)多态

多态是指同一个方法在不同的对象上调用时,可以有不同的行为。多态是面向对象编程的三大特性之一,它允许我们编写更通用的代码。

1. 方法重载与方法覆盖的区别

  • 方法重载(Overloading)

    • 在同一个类中,允许定义多个同名的方法,但这些方法的参数列表必须不同。
    • 方法重载是编译时多态的体现。
  • 方法覆盖(Overriding)

    • 在子类中重新定义父类的方法。被覆盖的方法必须具有相同的方法名、参数列表和返回类型。
    • 方法覆盖是运行时多态的体现。

2. 动态绑定与静态绑定

  • 静态绑定(Static Binding)

    • 在编译时确定方法的调用。静态绑定通常用于方法重载。
  • 动态绑定(Dynamic Binding)

    • 在运行时确定方法的调用。动态绑定通常用于方法覆盖。

3. instanceof运算符

instanceof运算符用于判断一个对象是否是某个类的实例。

public class PolymorphismExample {
    // 定义父类
    public static class Animal {
        public void makeSound() {
            System.out.println("动物发出声音");
        }
    }

    // 定义子类
    public static class Dog extends Animal {
        @Override
        public void makeSound() {
            System.out.println("狗汪汪叫");
        }
    }

    public static void main(String[] args) {
        // 创建父类对象
        Animal animal = new Animal();
        animal.makeSound(); // 输出:动物发出声音

        // 创建子类对象
        Animal dog = new Dog();
        dog.makeSound(); // 输出:狗汪汪叫(动态绑定)

        // 使用instanceof判断对象类型
        if (dog instanceof Dog) {
            System.out.println("dog是Dog类的实例");
        } else {
            System.out.println("dog不是Dog类的实例");
        }
    }
}

(九)接口与抽象类

接口和抽象类是Java中用于实现抽象编程的两种机制。它们都允许我们定义方法的签名,但接口和抽象类在实现细节上有很大的不同。

1. 接口

接口是一种特殊的类,它只能包含常量和抽象方法。接口中的方法默认是publicabstract的,而接口中的变量默认是publicstaticfinal的。

  • 接口的定义

    public interface Animal {
        void makeSound(); // 默认是public abstract
    }
    
  • 接口的实现

    public class Dog implements Animal {
        @Override
        public void makeSound() {
            System.out.println("狗汪汪叫");
        }
    }
    

2. 抽象类

抽象类是一种不能被实例化的类,它允许我们定义抽象方法。抽象方法没有实现,必须在子类中被实现。

  • 抽象类的定义

    public abstract class Animal {
        public abstract void makeSound(); // 抽象方法
    }
    
  • 抽象类的继承

    public class Dog extends Animal {
        @Override
        public void makeSound() {
            System.out.println("狗汪汪叫");
        }
    }
    

3. 接口与抽象类的区别

  • 接口

    • 接口只能包含常量和抽象方法。
    • 接口中的方法默认是publicabstract的。
    • 接口中的变量默认是publicstaticfinal的。
    • 一个类可以实现多个接口。
  • 抽象类

    • 抽象类可以包含抽象方法和具体方法。
    • 抽象类中的方法可以有实现。
    • 抽象类中的变量可以是任意修饰符。
    • 一个类只能继承一个抽象类。

4. 常见代码示例

public class InterfaceAndAbstractClassExample {
    // 定义接口
    public static interface Animal {
        void makeSound();
    }

    // 定义抽象类
    public static abstract class AbstractAnimal {
        public abstract void makeSound();
    }

    // 实现接口
    public static class Dog implements Animal {
        @Override
        public void makeSound() {
            System.out.println("狗汪汪叫");
        }
    }

    // 继承抽象类
    public static class Cat extends AbstractAnimal {
        @Override
        public void makeSound() {
            System.out.println("猫喵喵叫");
        }
    }

    public static void main(String[] args) {
        // 创建接口的实例
        Animal dog = new Dog();
        dog.makeSound(); // 输出:狗汪汪叫

        // 创建抽象类的实例
        AbstractAnimal cat = new Cat();
        cat.makeSound(); // 输出:猫喵喵叫
    }
}

(十)内部类

内部类是定义在另一个类
内部的类。内部类可以访问外部类的成员变量和方法,而外部类也可以访问内部类的成员变量和方法。

1. 成员内部类

成员内部类是定义在类的成员位置的类。它可以直接访问外部类的成员变量和方法。

public class OuterClass {
    private String name = "Kimi";

    public class InnerClass {
        public void printName() {
            System.out.println("外部类的名称: " + name);
        }
    }
}

2. 局部内部类

局部内部类是定义在方法内部的类。它只能在该方法中使用。

public class OuterClass {
    public void printInfo() {
        class LocalInnerClass {
            public void printMessage() {
                System.out.println("这是一个局部内部类");
            }
        }

        LocalInnerClass localInner = new LocalInnerClass();
        localInner.printMessage();
    }
}

3. 匿名内部类

匿名内部类是没有名称的内部类。它通常用于创建接口或抽象类的实例。

public class OuterClass {
    public void printInfo() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("这是一个匿名内部类");
            }
        };

        runnable.run();
    }
}

4. 静态内部类

静态内部类是定义在外部类内部的静态类。它不能访问外部类的非静态成员变量和方法,但可以访问静态成员变量和方法。

public class OuterClass {
    private static String name = "Kimi";

    public static class StaticInnerClass {
        public void printName() {
            System.out.println("外部类的名称: " + name);
        }
    }
}

5. 常见代码示例

public class InnerClassExample {
    // 成员内部类
    public static class OuterClass {
        private String name = "Kimi";

        public class InnerClass {
            public void printName() {
                System.out.println("外部类的名称: " + name);
            }
        }
    }

    // 局部内部类
    public static class LocalInnerClassExample {
        public void printInfo() {
            class LocalInnerClass {
                public void printMessage() {
                    System.out.println("这是一个局部内部类");
                }
            }

            LocalInnerClass localInner = new LocalInnerClass();
            localInner.printMessage();
        }
    }

    // 匿名内部类
    public static class AnonymousInnerClassExample {
        public void printInfo() {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("这是一个匿名内部类");
                }
            };

            runnable.run();
        }
    }

    // 静态内部类
    public static class StaticInnerClassExample {
        private static String name = "Kimi";

        public static class StaticInnerClass {
            public void printName() {
                System.out.println("外部类的名称: " + name);
            }
        }
    }

    public static void main(String[] args) {
        // 成员内部类
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.printName(); // 输出:外部类的名称: Kimi

        // 局部内部类
        LocalInnerClassExample example1 = new LocalInnerClassExample();
        example1.printInfo(); // 输出:这是一个局部内部类

        // 匿名内部类
        AnonymousInnerClassExample example2 = new AnonymousInnerClassExample();
        example2.printInfo(); // 输出:这是一个匿名内部类

        // 静态内部类
        StaticInnerClassExample.StaticInnerClass staticInner = new StaticInnerClassExample.StaticInnerClass();
        staticInner.printName(); // 输出:外部类的名称: Kimi
    }
}

(十一)Java集合框架

Java集合框架提供了一系列的接口和实现类,用于存储和管理对象集合。集合框架的主要接口包括CollectionListSetMap

1. 集合接口与实现类

  • Collection接口

    • Collection是集合框架的根接口,它定义了集合的基本操作,如添加、删除和遍历元素。
  • List接口

    • List接口继承自Collection接口,它是一个有序的集合,允许重复的元素。
      • ArrayList:基于动态数组实现的List,适合频繁的随机访问。
      • LinkedList:基于双向链表实现的List,适合频繁的插入和删除操作。
  • Set接口

    • Set接口继承自Collection接口,它是一个不包含重复元素的集合。
      • HashSet:基于哈希表实现的Set,元素无序。
      • TreeSet:基于红黑树实现的Set,元素有序。
  • Map接口

    • Map接口是一个键值对的集合,键是唯一的,但值可以重复。
      • HashMap:基于哈希表实现的Map,键值对无序。
      • TreeMap:基于红黑树实现的Map,键值对有序。

2. 集合的遍历

  • for-each循环

    • for-each循环是一种简化的循环,用于遍历集合中的元素。
      List<String> list = Arrays.asList("Kimi", "Alice", "Bob");
      for (String name : list) {
          System.out.println(name);
      }
      
  • Iterator迭代器

    • Iterator是一个用于遍历集合的接口,它提供了一种通用的方式来访问集合中的元素。
      List<String> list = Arrays.asList("Kimi", "Alice", "Bob");
      Iterator<String> iterator = list.iterator();
      while (iterator.hasNext()) {
          String name = iterator.next();
          System.out.println(name);
      }
      
  • Stream API

    • Stream API是Java 8引入的一种新的集合操作方式,它提供了一种更简洁的方式来处理集合。
      List<String> list = Arrays.asList("Kimi", "Alice", "Bob");
      list.stream()
          .filter(name -> name.startsWith("A")) // 过滤以A开头的名字
          .forEach(System.out::println); // 输出过滤后的结果
      

3. 常见代码示例

public class CollectionExample {
    // List示例
    public static void listExample() {
        List<String> list = new ArrayList<>();
        list.add("Kimi");
        list.add("Alice");
        list.add("Bob");

        System.out.println("List中的元素:");
        for (String name : list) {
            System.out.println(name);
        }
    }

    // Set示例
    public static void setExample() {
        Set<String> set = new HashSet<>();
        set.add("Kimi");
        set.add("Alice");
        set.add("Bob");

        System.out.println("Set中的元素:");
        for (String name : set) {
            System.out.println(name);
        }
    }

    // Map示例
    public static void mapExample() {
        Map<String, Integer> map = new HashMap<>();
        map.put("Kimi", 25);
        map.put("Alice", 30);
        map.put("Bob", 35);

        System.out.println("Map中的元素:");
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    public static void main(String[] args) {
        listExample();
        setExample();
        mapExample();
    }
}

(十二)Java常用类库

Java提供了丰富的类库,用于处理常见的编程任务,如字符串操作、日期时间处理、数学计算等。

1. 字符串类

String类是Java中最常用的类之一,它用于表示字符串。字符串是不可变的,一旦创建后不能修改。

  • 常用方法
    • length():返回字符串的长度。

      String str = "Hello";
      int length = str.length(); // 结果为5
      
    • charAt(int index):返回指定索引处的字符。

      char c = str.charAt(0); // 结果为'H'
      
    • substring(int beginIndex, int endIndex):返回字符串的子串。

      String subStr = str.substring(0, 3); // 结果为"Hel"
      
    • equals(Object anObject):比较两个字符串是否相等。

      boolean isEqual = str.equals("Hello"); // 结果为true
      
    • compareTo(String anotherString):比较两个字符串的字典顺序。

      int comparison = str.compareTo("Hello"); // 结果为0
      

2. 包装类

包装类是基本数据类型的类版本,它们允许我们将基本数据类型作为对象处理。

  • 自动装箱与自动拆箱
    • 自动装箱:将基本数据类型自动转换为对应的包装类。

      Integer num = 10; // 自动装箱
      
    • 自动拆箱:将包装类自动转换为对应的基本数据类型。

      int value = num; // 自动拆箱
      

3. 日期与时间类

Java提供了多种日期和时间类,用于处理日期和时间。

  • java.util.Date

    • Date类用于表示日期和时间。
      Date date = new Date();
      System.out.println(date.toString());
      
  • java.time

    • java.time包是Java 8引入的新的日期和时间API,它提供了更强大的日期和时间处理功能。
      • LocalDate:表示日期(年、月、日)。
      • LocalTime:表示时间(时、分、秒)。
      • LocalDateTime:表示日期和时间。
      • DateTimeFormatter:用于格式化日期和时间。
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDate = localDateTime.format(formatter);
        System.out.println(formattedDate);
        

4. 数学类

Math类提供了各种数学计算方法。

  • 常用方法
    • abs(double a):返回参数的绝对值。

      double absValue = Math.abs(-10.5); // 结果为10.5
      
    • sqrt(double a):返回参数的平方根。

      double sqrtValue = Math.sqrt(16); // 结果为4.0
      
    • pow(double a, double b):返回ab次幂。

      double powValue = Math.pow(2, 3); // 结果为8.0
      
    • random():返回一个随机数。

      double randomValue = Math.random(); // 返回一个0到1之间的随机数
      

5. IO流

Java的IO流用于处理输入和输出操作。IO流分为字节流和字符流。

  • 字节流

    • InputStream:输入字节流。
    • OutputStream:输出字节流。
      // 读取文件
      try (InputStream inputStream = new FileInputStream("example.txt")) {
          int data;
          while ((data = inputStream.read()) != -1) {
              System.out.print((char) data);
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
      
      // 写入文件
      try (OutputStream outputStream = new FileOutputStream("example.txt")) {
          String str = "Hello, World!";
          outputStream.write(str.getBytes());
      } catch (IOException e) {
          e.printStackTrace();
      }
      
  • 字符流

    • Reader:输入字符流。
    • Writer:输出字符流。
      // 读取文件
      try (Reader reader = new FileReader("example.txt")) {
          int data;
          while ((data = reader.read()) != -1) {
              System.out.print((char) data);
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
      
      // 写入文件
      try (Writer writer = new FileWriter("example.txt")) {
          String str = "Hello, World!";
          writer.write(str);
      } catch (IOException e) {
          e.printStackTrace();
      }
      

6. 异常处理

异常处理用于处理程序运行时可能出现的错误。

  • try-catch

    • try块用于包裹可能抛出异常的代码,catch块用于捕获和处理异常。
      try {
          int result = 10 / 0;
      } catch (ArithmeticException e) {
          System.out.println("发生了算术异常: " + e.getMessage());
      }
      
  • finally

    • finally块用于在try块和catch块执行完毕后执行,无论是否发生异常都会执行。
      try {
          int result = 10 / 0;
      } catch (ArithmeticException e) {
          System.out.println("发生了算术异常: " + e.getMessage());
      } finally {
          System.out.println("finally块被执行");
      }
      
  • 自定义异常

    • 自定义异常可以通过继承Exception类或其子类来实现。
      public class CustomException extends Exception {
          public CustomException(String message) {
              super(message);
          }
      }
      
      public class ExceptionExample {
          public static void main(String[] args) {
              try {
                  throw new CustomException("这是一个自定义异常");
              } catch (CustomException e) {
                  System.out.println("捕获到自定义异常: " + e.getMessage());
              }
          }
      }
      

7. 常见代码示例

public class CommonClassesExample {
    // 字符串操作
    public static void stringExample() {
        String str = "Hello";
        int length = str.length();
        char c = str.charAt(0);
        String subStr = str.substring(0, 3);
        boolean isEqual = str.equals("Hello");
        int comparison = str.compareTo("Hello");

        System.out.println("字符串长度: " + length);
        System.out.println("字符串第一个字符: " + c);
        System.out.println("字符串子串: " + subStr);
        System.out.println("字符串是否相等: " + isEqual);
        System.out.println("字符串比较结果: " + comparison);
    }

    // 日期时间操作
    public static void dateTimeExample() {
        Date date = new Date();
        System.out.println("当前日期和时间: " + date.toString());

        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDate = localDateTime.format(formatter);
        System.out.println("格式化后的日期和时间: " + formattedDate);
    }

    // 数学计算
    public static void mathExample() {
        double absValue = Math.abs(-10.5);
        double sqrtValue = Math.sqrt(16);
        double powValue = Math.pow(2, 3);
        double randomValue = Math.random();

        System.out.println("绝对值: " + absValue);
        System.out.println("平方根: " + sqrtValue);
        System.out.println("幂运算结果: " + powValue);
        System.out.println("随机数: " + randomValue);
    }

    // IO流操作
    public static void ioExample() {
        // 读取文件
        try (InputStream inputStream = new FileInputStream("example.txt")) {
            int data;
            while ((data = inputStream.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 写入文件
        try (OutputStream outputStream = new FileOutputStream("example.txt")) {
            String str = "Hello, World!";
            outputStream.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 异常处理
    public static void exceptionExample() {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("发生了算术异常: " + e.getMessage());
        } finally {
            System.out.println("finally块被执行");
        }
    }

    public static void main(String[] args) {
        stringExample();
        dateTimeExample();
        mathExample();
        ioExample();
        exceptionExample();
    }
}

(十三)Java多线程

多线程是Java的一个重要特性,它允许程序同时执行多个任务。多线程可以提高程序的性能和响应能力。

1. 线程的创建

在Java中,可以通过继承Thread类或实现Runnable接口来创建线程。

  • 继承Thread

    public class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("线程正在运行");
        }
    }
    
  • 实现Runnable接口

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("线程正在运行");
        }
    }
    

2. 线程的生命周期

线程的生命周期包括新建、就绪
、运行、阻塞和死亡五个状态。

  • 新建状态:线程被创建但尚未启动。
  • 就绪状态:线程已经启动,等待CPU调度。
  • 运行状态:线程正在执行。
  • 阻塞状态:线程因为某些原因暂停执行,如等待I/O操作或等待锁。
  • 死亡状态:线程执行完毕或被终止。

3. 线程的同步

线程同步用于解决多线程环境下的数据共享问题。Java提供了多种同步机制,如synchronized关键字和Lock接口。

  • synchronized关键字

    • synchronized关键字用于同步方法或代码块,确保同一时间只有一个线程可以访问共享资源。
      public class Counter {
          private int count = 0;
      
          public synchronized void increment() {
              count++;
          }
      
          public synchronized int getCount() {
              return count;
          }
      }
      
  • Lock接口

    • Lock接口提供了一种更灵活的同步机制,它允许更细粒度的控制。
      public class Counter {
          private int count = 0;
          private Lock lock = new ReentrantLock();
      
          public void increment() {
              lock.lock();
              try {
                  count++;
              } finally {
                  lock.unlock();
              }
          }
      
          public int getCount() {
              lock.lock();
              try {
                  return count;
              } finally {
                  lock.unlock();
              }
          }
      }
      

4. 线程的通信

线程通信用于解决线程之间的协作问题。Java提供了waitnotifynotifyAll方法用于线程通信。

  • wait方法

    • wait方法使当前线程进入等待状态,直到被其他线程唤醒。
      synchronized (this) {
          while (condition) {
              wait();
          }
      }
      
  • notifynotifyAll方法

    • notify方法唤醒一个等待的线程,notifyAll方法唤醒所有等待的线程。
      synchronized (this) {
          notify();
      }
      

5. 常见代码示例

public class MultiThreadExample {
    // 继承Thread类
    public static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("线程正在运行");
        }
    }

    // 实现Runnable接口
    public static class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("线程正在运行");
        }
    }

    // 线程同步示例
    public static class Counter {
        private int count = 0;

        public synchronized void increment() {
            count++;
        }

        public synchronized int getCount() {
            return count;
        }
    }

    // 线程通信示例
    public static class ProducerConsumerExample {
        private int count = 0;

        public synchronized void produce() throws InterruptedException {
            while (count >= 1) {
                wait();
            }
            count++;
            System.out.println("生产者生产,当前数量: " + count);
            notifyAll();
        }

        public synchronized void consume() throws InterruptedException {
            while (count <= 0) {
                wait();
            }
            count--;
            System.out.println("消费者消费,当前数量: " + count);
            notifyAll();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建线程
        MyThread thread1 = new MyThread();
        thread1.start();

        Thread thread2 = new Thread(new MyRunnable());
        thread2.start();

        // 线程同步
        Counter counter = new Counter();
        Thread incrementThread = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        Thread incrementThread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        incrementThread.start();
        incrementThread2.start();
        incrementThread.join();
        incrementThread2.join();
        System.out.println("最终计数: " + counter.getCount());

        // 线程通信
        ProducerConsumerExample example = new ProducerConsumerExample();
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    example.produce();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    example.consume();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        producer.start();
        consumer.start();
    }
}

(十四)Java网络编程

Java提供了丰富的网络编程支持,用于开发基于网络的应用程序。Java的网络编程主要涉及套接字(Socket)编程和基于HTTP协议的Web开发。

1. TCP网络编程

TCP是一种面向连接的协议,它提供可靠的数据传输服务。在Java中,可以通过ServerSocketSocket类来实现TCP网络编程。

  • 服务器端

    public class TCPServer {
        public static void main(String[] args) throws IOException {
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器已启动,等待客户端连接...");
    
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("客户端已连接");
    
                new Thread(new ClientHandler(socket)).start();
            }
        }
    
        static class ClientHandler implements Runnable {
            private Socket socket;
    
            public ClientHandler(Socket socket) {
                this.socket = socket;
            }
    
            @Override
            public void run() {
                try (InputStream inputStream = socket.getInputStream();
                     OutputStream outputStream = socket.getOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  • 客户端

    public class TCPClient {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1", 8080);
            System.out.println("已连接到服务器");
    
            try (OutputStream outputStream = socket.getOutputStream();
                 InputStream inputStream = socket.getInputStream()) {
                outputStream.write("Hello, Server!".getBytes());
                byte[] buffer = new byte[1024];
                int length = inputStream.read(buffer);
                System.out.println("服务器响应: " + new String(buffer, 0, length));
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

2. UDP网络编程

UDP是一种无连接的协议,它不保证数据的可靠传输。在Java中,可以通过DatagramSocketDatagramPacket类来实现UDP网络编程。

  • 服务器端

    public class UDPServer {
        public static void main(String[] args) throws IOException {
            DatagramSocket socket = new DatagramSocket(8080);
            System.out.println("服务器已启动,等待客户端消息...");
    
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    
            while (true) {
                socket.receive(packet);
                String message = new String(packet.getData(), 0, packet.getLength());
                System.out.println("收到客户端消息: " + message);
    
                // 发送响应
                String response = "Hello, Client!";
                DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.length(), packet.getAddress(), packet.getPort());
                socket.send(responsePacket);
            }
        }
    }
    
  • 客户端

    public class UDPClient {
        public static void main(String[] args) throws IOException {
            DatagramSocket socket = new DatagramSocket();
            InetAddress address = InetAddress.getByName("127.0.0.1");
    
            String message = "Hello, Server!";
            byte[] buffer = message.getBytes();
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 8080);
            socket.send(packet);
    
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            socket.receive(receivePacket);
            String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("服务器响应: " + response);
    
            socket.close();
        }
    }
    

3. HTTP协议与Web开发基础

HTTP协议是Web开发的基础。Java提供了HttpURLConnection类用于发送HTTP请求和接收响应。

public class HttpExample {
    public static void main(String[] args) throws
 IOException {
        URL url = new URL("http://example.com");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        int responseCode = connection.getResponseCode();
        System.out.println("响应码: " + responseCode);

        try (InputStream inputStream = connection.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
    }
}

(十五)Java数据库编程(JDBC)

Java数据库连接(JDBC)是Java用于访问数据库的API。通过JDBC,可以连接数据库、执行SQL语句和处理结果集。

1. JDBC概述

JDBC提供了以下接口和类:

  • DriverManager:用于获取数据库连接。
  • Connection:表示与数据库的连接。
  • Statement:用于执行SQL语句。
  • ResultSet:用于处理查询结果。

2. 数据库连接与操作

  • 连接数据库

    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");
    
  • 执行SQL语句

    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT * FROM users");
    
  • 处理结果集

    while (resultSet.next()) {
        String name = resultSet.getString("name");
        int age = resultSet.getInt("age");
        System.out.println("姓名: " + name + ", 年龄: " + age);
    }
    

3. 事务处理

事务用于保证数据库操作的原子性。在Java中,可以通过设置事务的隔离级别和提交/回滚事务来管理事务。

  • 设置事务隔离级别

    connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
    
  • 提交事务

    connection.commit();
    
  • 回滚事务

    connection.rollback();
    

4. 常见代码示例

public class JdbcExample {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 连接数据库
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");

            // 创建Statement
            statement = connection.createStatement();

            // 执行查询
            resultSet = statement.executeQuery("SELECT * FROM users");

            // 处理结果集
            while (resultSet.next()) {
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                System.out.println("姓名: " + name + ", 年龄: " + age);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

(十六)Java注解与反射

2. 自定义注解

自定义注解可以通过@interface关键字来定义。注解可以有成员变量,这些成员变量在使用注解时需要提供值。

public @interface MyAnnotation {
    String value(); // 必须指定的成员变量
    int age() default 18; // 可选的成员变量,有默认值
}

使用自定义注解:

@MyAnnotation(value = "Kimi", age = 25)
public class MyClass {
}

3. 反射机制

反射是Java的一种动态机制,允许程序在运行时检查和操作类、方法、字段等信息。

  • 获取Class对象

    Class<?> clazz = MyClass.class; // 通过类名获取
    Class<?> clazz2 = new MyClass().getClass(); // 通过对象获取
    Class<?> clazz3 = Class.forName("com.example.MyClass"); // 通过类的全限定名获取
    
  • 获取类的信息

    Field[] fields = clazz.getDeclaredFields(); // 获取所有字段
    Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法
    Constructor<?>[] constructors = clazz.getDeclaredConstructors(); // 获取所有构造方法
    
  • 通过反射创建对象

    Constructor<?> constructor = clazz.getDeclaredConstructor();
    constructor.setAccessible(true); // 如果是私有构造方法,需要设置为可访问
    Object instance = constructor.newInstance();
    
  • 通过反射调用方法

    Method method = clazz.getDeclaredMethod("methodName", String.class);
    method.setAccessible(true); // 如果是私有方法,需要设置为可访问
    method.invoke(instance, "Hello");
    
  • 通过反射访问字段

    Field field = clazz.getDeclaredField("fieldName");
    field.setAccessible(true); // 如果是私有字段,需要设置为可访问
    Object value = field.get(instance); // 获取字段值
    field.set(instance, "newValue"); // 设置字段值
    

4. 常见代码示例

public class ReflectionExample {
    public static class MyClass {
        private String name = "Kimi";

        public void printName() {
            System.out.println("名字: " + name);
        }
    }

    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> clazz = MyClass.class;

        // 获取类的信息
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("字段: " + field.getName());
        }

        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("方法: " + method.getName());
        }

        // 通过反射创建对象
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object instance = constructor.newInstance();

        // 通过反射调用方法
        Method method = clazz.getDeclaredMethod("printName");
        method.setAccessible(true);
        method.invoke(instance);

        // 通过反射访问字段
        Field field = clazz.getDeclaredField("name");
        field.setAccessible(true);
        String value = (String) field.get(instance);
        System.out.println("字段值: " + value);
        field.set(instance, "Alice");
        method.invoke(instance); // 输出:名字: Alice
    }
}

(十七)Java设计模式

设计模式是解决常见问题的通用解决方案。Java中常用的设计模式包括创建型模式、结构型模式和行为型模式。

1. 创建型设计模式

创建型设计模式用于创建对象,同时隐藏创建逻辑,而不是直接使用new操作符。

  • 单例模式

    • 确保一个类只有一个实例,并提供一个全局访问点。
      public class Singleton {
          private static Singleton instance;
      
          private Singleton() {
          }
      
          public static Singleton getInstance() {
              if (instance == null) {
                  synchronized (Singleton.class) {
                      if (instance == null) {
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }
      
  • 工厂模式

    • 提供一个创建对象的接口,让子类决定实例化哪一个类。
      public interface Shape {
          void draw();
      }
      
      public class Circle implements Shape {
          @Override
          public void draw() {
              System.out.println("画一个圆");
          }
      }
      
      public class Rectangle implements Shape {
          @Override
          public void draw() {
              System.out.println("画一个矩形");
          }
      }
      
      public class ShapeFactory {
          public Shape getShape(String shapeType) {
              if (shapeType == null) {
                  return null;
              }
              if (shapeType.equalsIgnoreCase("CIRCLE")) {
                  return new Circle();
              } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
                  return new Rectangle();
              }
              return null;
          }
      }
      
  • 建造者模式

    • 用于创建一个复杂的对象,同时隐藏对象的创建逻辑。
      public class BuilderExample {
          private String name;
          private int age;
          private String address;
      
          public static class Builder {
              private String name;
              private int age;
              private String address;
      
              public Builder setName(String name) {
                  this.name = name;
                  return this;
              }
      
              public Builder setAge(int age) {
                  this.age = age;
                  return this;
              }
      
              public Builder setAddress(String address) {
                  this.address = address;
                  return this;
              }
      
              public BuilderExample build() {
                  return new BuilderExample(this);
              }
          }
      
          private BuilderExample(Builder builder) {
              this.name = builder.name;
              this.age = builder.age;
              this.address = builder.address;
          }
      
          @Override
          public String toString() {
              return "BuilderExample{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      ", address='" + address + '\'' +
                      '}';
          }
      }
      

2. 结构型设计模式

结构型设计模式用于处理类或对象的组合。

  • 适配器模式

    • 允许将不兼容的接口转换为一个可以使用的兼容接口。
      public interface MediaPlayer {
          void play(String audioType, String fileName);
      }
      
      public interface AdvancedMediaPlayer {
          void playVlc(String fileName);
          void playMp4(String fileName);
      }
      
      public class VlcPlayer implements AdvancedMediaPlayer {
          @Override
          public void playVlc(String fileName) {
              System.out.println("Playing vlc file. Name: " + fileName);
          }
      
          @Override
          public void playMp4(String fileName) {
              // Do nothing
          }
      }
      
      public class Mp4Player implements AdvancedMediaPlayer {
          @Override
          public void playVlc(String fileName) {
              // Do nothing
          }
      
          @Override
          public void playMp4(String fileName) {
              System.out.println("Playing mp4 file. Name: " + fileName);
          }
      }
      
      public class MediaAdapter implements MediaPlayer {
          private AdvancedMediaPlayer advancedMediaPlayer;
      
          public MediaAdapter(String audioType) {
              if (audioType.equalsIgnoreCase("vlc")) {
                  advancedMediaPlayer = new VlcPlayer();
              } else if (audioType.equalsIgnoreCase("mp4")) {
                  advancedMediaPlayer = new Mp4Player();
              }
          }
      
          @Override
          public void play(String audioType, String fileName) {
              if (audioType.equalsIgnoreCase("vlc")) {
                  advancedMediaPlayer.playVlc(fileName);
              } else if (audioType.equalsIgnoreCase("mp4")) {
                  advancedMediaPlayer.playMp4(fileName);
              }
          }
      }
      
  • 装饰器模式

    • 动态地给一个对象添加额外的职责。
      public interface Component {
          void operation();
      }
      
      public class ConcreteComponent implements Component {
          @Override
          public void operation() {
              System.out.println("具体组件的操作");
          }
      }
      
      public abstract class Decorator implements Component {
          protected Component component;
      
          public Decorator(Component component) {
              this.component = component;
          }
      
          @Override
          public void operation() {
              component.operation();
          }
      }
      
      public class ConcreteDecoratorA extends Decorator {
          public ConcreteDecoratorA(Component component) {
              super(component);
          }
      
          @Override
          public void operation() {
              super.operation();
              addedBehavior();
          }
      
          private void addedBehavior() {
              System.out.println("添加额外的行为A");
          }
      }
      
      public class ConcreteDecoratorB extends Decorator {
          public ConcreteDecoratorB(Component component) {
              super(component);
          }
      
          @Override
          public void operation() {
              super.operation();
              addedBehavior();
          }
      
          private void addedBehavior() {
              System.out.println("添加额外的行为B");
          }
      }
      
  • 代理模式

    • 为其他对象提供一种代理以控制对这个对象的访问。
      public interface Subject {
          void request();
      }
      
      public class RealSubject implements Subject {
          @Override
          public void request(){
              System.out.println("真实主题的请求");
          }
      }
      
      public class Proxy implements Subject {
          private RealSubject realSubject;
      
          @Override
          public void request() {
              preRequest();
              if (realSubject == null) {
                  realSubject = new RealSubject();
              }
              realSubject.request();
              postRequest();
          }
      
          private void preRequest() {
              System.out.println("代理的预处理");
          }
      
          private void postRequest() {
              System.out.println("代理的后处理");
          }
      }
      

3. 行为型设计模式

行为型设计模式用于处理类或对象之间的通信。

  • 策略模式

    • 定义一系列算法,将每个算法封装起来,并使它们可以互换。
      public interface Strategy {
          int doOperation(int num1, int num2);
      }
      
      public class OperationAdd implements Strategy {
          @Override
          public int doOperation(int num1, int num2) {
              return num1 + num2;
          }
      }
      
      public class OperationSubtract implements Strategy {
          @Override
          public int doOperation(int num1, int num2) {
              return num1 - num2;
          }
      }
      
      public class Context {
          private Strategy strategy;
      
          public Context(Strategy strategy) {
              this.strategy = strategy;
          }
      
          public int executeStrategy(int num1, int num2) {
              return strategy.doOperation(num1, num2);
          }
      }
      
  • 模板方法模式

    • 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
      public abstract class AbstractClass {
          public final void templateMethod() {
              step1();
              step2();
              step3();
          }
      
          protected abstract void step1();
      
          protected abstract void step2();
      
          protected void step3() {
              System.out.println("默认的第三步");
          }
      }
      
      public class ConcreteClassA extends AbstractClass {
          @Override
          protected void step1() {
              System.out.println("具体实现A的第一步");
          }
      
          @Override
          protected void step2() {
              System.out.println("具体实现A的第二步");
          }
      }
      
      public class ConcreteClassB extends AbstractClass {
          @Override
          protected void step1() {
              System.out.println("具体实现B的第一步");
          }
      
          @Override
          protected void step2() {
              System.out.println("具体实现B的第二步");
          }
      }
      
  • 观察者模式

    • 定义对象间的一种一对多的依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都得到通知并自动更新。
      public interface Observer {
          void update(String message);
      }
      
      public interface Subject {
          void register(Observer obj);
          void unregister(Observer obj);
          void notifyObservers();
      }
      
      public class ConcreteSubject implements Subject {
          private List<Observer> observers = new ArrayList<>();
      
          @Override
          public void register(Observer obj) {
              observers.add(obj);
          }
      
          @Override
          public void unregister(Observer obj) {
              observers.remove(obj);
          }
      
          @Override
          public void notifyObservers() {
              for (Observer observer : observers) {
                  observer.update("状态已改变");
              }
          }
      }
      
      public class ConcreteObserver implements Observer {
          private String name;
      
          public ConcreteObserver(String name) {
              this.name = name;
          }
      
          @Override
          public void update(String message) {
              System.out.println(name + "收到消息: " + message);
          }
      }
      

4. 常见代码示例

public class DesignPatternsExample {
    // 单例模式
    public static class SingletonExample {
        private static SingletonExample instance;

        private SingletonExample() {
        }

        public static SingletonExample getInstance() {
            if (instance == null) {
                synchronized (SingletonExample.class) {
                    if (instance == null) {
                        instance = new SingletonExample();
                    }
                }
            }
            return instance;
        }
    }

    // 工厂模式
    public static class FactoryExample {
        public static void main(String[] args) {
            ShapeFactory shapeFactory = new ShapeFactory();

            Shape shape1 = shapeFactory.getShape("CIRCLE");
            shape1.draw();

            Shape shape2 = shapeFactory.getShape("RECTANGLE");
            shape2.draw();
        }
    }

    // 建造者模式
    public static class BuilderExample {
        public static void main(String[] args) {
            BuilderExample example = new BuilderExample.Builder()
                    .setName("Kimi")
                    .setAge(25)
                    .setAddress("Beijing")
                    .build();

            System.out.println(example);
        }
    }

    // 适配器模式
    public static class AdapterExample {
        public static void main(String[] args) {
            MediaPlayer mediaPlayer = new MediaAdapter("vlc");
            mediaPlayer.play("vlc", "example.vlc");

            mediaPlayer = new MediaAdapter("mp4");
            mediaPlayer.play("mp4", "example.mp4");
        }
    }

    // 装饰器模式
    public static class DecoratorExample {
        public static void main(String[] args) {
            Component component = new ConcreteComponent();
            Component decoratedComponent = new ConcreteDecoratorA(component);
            decoratedComponent.operation();

            decoratedComponent = new ConcreteDecoratorB(decoratedComponent);
            decoratedComponent.operation();
        }
    }

    // 代理模式
    public static class ProxyExample {
        public static void main(String[] args) {
            Subject proxy = new Proxy();
            proxy.request();
        }
    }

    // 策略模式
    public static class StrategyExample {
        public static void main(String[] args) {
            Context context = new Context(new OperationAdd());
            System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

            context = new Context(new OperationSubtract());
            System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
        }
    }

    // 模板方法模式
    public static class TemplateMethodExample {
        public static void main(String[] args) {
            AbstractClass classA = new ConcreteClassA();
            classA.templateMethod();

            AbstractClass classB = new ConcreteClassB();
            classB.templateMethod();
        }
    }

    // 观察者模式
    public static class ObserverExample {
        public static void main(String[] args) {
            Subject subject = new ConcreteSubject();

            Observer observer1 = new ConcreteObserver("Observer1");
            Observer observer2 = new ConcreteObserver("Observer2");

            subject.register(observer1);
            subject.register(observer2);

            subject.notifyObservers();
        }
    }

    public static void main(String[] args) {
        SingletonExample singleton = SingletonExample.getInstance();
        System.out.println(singleton);

        FactoryExample.main(args);
        BuilderExample.main(args);
        AdapterExample.main(args);
        DecoratorExample.main(args);
        ProxyExample.main(args);
        StrategyExample.main(args);
        TemplateMethodExample.main(args);
        ObserverExample.main(args);
    }
}
posted @ 2025-04-16 12:47  软件职业规划  阅读(194)  评论(0)    收藏  举报