Java基础知识一

news/2025/2/12 1:36:46/文章来源:https://www.cnblogs.com/qiaozc/p/18710822

Java 基础知识文档

2025 年 2 月 12 日•内容由 AI 生成,不能完全保障真实

我将要面试,帮我生成一份总结java基础知识的markdown文档。要求涵盖所有的java基础知识点,并且要结构清晰,内容简洁。

Java 基础知识总结

一、Java 概述

1.1 Java 简介

Java 是由 Sun Microsystems 公司(2010 年被 Oracle 收购)于 1995 年推出的高级编程语言。它具有以下显著特点:

  • 面向对象:Java 采用面向对象的编程范式,支持封装、继承和多态等特性,使得代码更具可维护性、可扩展性和可复用性。
  • 跨平台:Java 程序通过编译器编译成字节码(.class 文件),字节码可以在不同操作系统上的 Java 虚拟机(JVM)中运行,实现了 “一次编写,到处运行”。
  • 安全性:Java 提供了安全机制,如字节码验证、安全管理器等,能够有效防止恶意代码的攻击。
  • 多线程:Java 内置了对多线程的支持,使得程序可以同时执行多个任务,提高了程序的并发性能。
  • 自动内存管理:Java 采用垃圾回收机制(GC),自动管理内存的分配和回收,减少了程序员手动管理内存的负担。

1.2 Java 平台

  • Java SE(Standard Edition):Java 标准版,是 Java 技术的基础,提供了核心的类库和开发工具,用于开发桌面和简单服务器应用。
  • Java EE(Enterprise Edition):Java 企业版,在 Java SE 的基础上提供了一系列的企业级服务和 API,如 Servlet、JSP、EJB 等,用于开发大型企业级应用。
  • Java ME(Micro Edition):Java 微型版,主要用于嵌入式系统和移动设备开发,提供了精简的类库和运行环境。

1.3 Java 跨平台原理

Java 程序的执行过程分为编译和运行两个阶段:

  • 编译阶段:Java 源文件(.java)通过 Java 编译器(javac)编译成字节码文件(.class)。字节码是一种中间代码,不针对特定的操作系统和硬件平台。
  • 运行阶段:字节码文件在 Java 虚拟机(JVM)中运行。JVM 是 Java 实现跨平台的关键,它负责加载字节码文件,并将字节码或编译成具体操作系统和硬件平台能够执行的机器码。不同的操作系统需要安装相应版本的 JVM,从而保证 Java 程序可以在不同的平台上运行。

二、数据类型

2.1 基本数据类型

Java 提供了 8 种基本数据类型,分为 4 类:整数类型、浮点类型、字符类型和布尔类型。

数据类型 位数 取值范围 默认值 示例
byte 8 -128 ~ 127 0 byte b = 10;
short 16 -32768 ~ 32767 0 short s = 100;
int 32 -2147483648 ~ 2147483647 0 int i = 1000;
long 64 -2^63 ~ 2^63 - 1 0L long l = 10000L;
float 32 单精度浮点数,有效位数约 7 位 0.0f float f = 3.14f;
double 64 双精度浮点数,有效位数约 15 位 0.0d double d = 3.14159;
char 16 0 ~ 65535 '\u0000' char c = 'A';
boolean 1 true 或 false false boolean flag = true;

2.2 引用数据类型

引用数据类型是对对象的引用,而不是对象本身。常见的引用数据类型包括:

  • 类(Class):类是对象的抽象,定义了对象的属性和方法。例如,String 类是 Java 中用于处理字符串的类。
String str = "Hello, World!";
  • 接口(Interface):接口是一种抽象类型,定义了一组方法的签名,但不包含方法的实现。类可以实现接口,从而实现接口中定义的方法。
interface Animal {void eat();
}class Dog implements Animal {@Overridepublic void eat() {System.out.println("Dog is eating.");}
}
  • 数组(Array):数组是一种存储相同类型数据的容器,数组的长度在创建时确定,并且不能改变。
int[] arr = new int[5];
arr[0] = 1;

三、变量和常量

3.1 变量

变量是程序中存储数据的基本单元,使用前需要先声明和初始化。变量的声明格式为:数据类型 变量名;,初始化格式为:变量名 = 值;。也可以在声明变量的同时进行初始化。

// 声明变量
int num;
// 初始化变量
num = 10;// 声明并初始化变量
int age = 20;

3.2 常量

常量是在程序运行过程中值不能被改变的量,使用 final 关键字修饰。常量在声明时必须进行初始化,并且不能再被赋值。

final double PI = 3.14159;
// 以下代码会编译错误,因为常量不能再被赋值
// PI = 3.14;

3.3 变量的作用域

变量的作用域是指变量在程序中可以被访问的范围。Java 中变量的作用域分为以下几种:

  • 类变量(静态变量):使用 static 关键字修饰,属于类,而不是类的实例。类变量在类加载时被初始化,在整个程序运行期间都存在。
class MyClass {static int classVar = 10;
}
  • 实例变量:属于类的实例,每个实例都有自己的一份实例变量。实例变量在创建对象时被初始化。
class MyClass {int instanceVar = 20;
}
  • 局部变量:定义在方法、构造方法或代码块中的变量,局部变量必须在使用前进行初始化,其作用域仅限于定义它的方法、构造方法或代码块。
public void method() {int localVar = 30;// 局部变量的作用域仅限于该方法
}

四、运算符

4.1 算术运算符

算术运算符用于执行基本的数学运算,包括加法(+)、减法(-)、乘法(*)、除法(/)、取模(%)、自增(++)和自减(--)。

int a = 10;
int b = 3;
int sum = a + b; // 加法
int diff = a - b; // 减法
int prod = a * b; // 乘法
int quot = a / b; // 除法
int rem = a % b; // 取模a++; // 自增
b--; // 自减

4.2 赋值运算符

赋值运算符用于将一个值赋给变量,常见的赋值运算符包括 =+=-=*=/=%=

int x = 5;
x += 3; // 相当于 x = x + 3;
x -= 2; // 相当于 x = x - 2;
x *= 4; // 相当于 x = x * 4;
x /= 2; // 相当于 x = x / 2;
x %= 3; // 相当于 x = x % 3;

4.3 比较运算符

比较运算符用于比较两个值的大小关系,返回一个布尔值(truefalse)。常见的比较运算符包括 ==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)。

int m = 10;
int n = 20;
boolean result1 = m == n; // false
boolean result2 = m != n; // true
boolean result3 = m > n;  // false
boolean result4 = m < n;  // true
boolean result5 = m >= n; // false
boolean result6 = m <= n; // true

4.4 逻辑运算符

逻辑运算符用于对布尔值进行逻辑运算,常见的逻辑运算符包括 &&(逻辑与)、||(逻辑或)、!(逻辑非)。

boolean p = true;
boolean q = false;
boolean andResult = p && q; // false
boolean orResult = p || q;  // true
boolean notResult = !p;     // false

4.5 位运算符

位运算符用于对整数类型的数据进行二进制位操作,常见的位运算符包括 &(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)、>>>(无符号右移)。

int num1 = 5; // 二进制: 0101
int num2 = 3; // 二进制: 0011
int andResult = num1 & num2; // 二进制: 0001,十进制: 1
int orResult = num1 | num2;  // 二进制: 0111,十进制: 7
int xorResult = num1 ^ num2; // 二进制: 0110,十进制: 6
int notResult = ~num1;       // 二进制: 1010,十进制: -6
int leftShift = num1 << 1;   // 二进制: 1010,十进制: 10
int rightShift = num1 >> 1;  // 二进制: 0010,十进制: 2

五、控制语句

5.1 条件语句

if - else 语句

if - else 语句用于根据条件的真假来执行不同的代码块。

int score = 80;
if (score >= 60) {System.out.println("及格");
} else {System.out.println("不及格");
}

if - else if - else 语句

当有多个条件需要判断时,可以使用 if - else if - else 语句。

int score = 80;
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 语句

switch 语句用于根据一个表达式的值来选择执行不同的代码块。

int day = 3;
switch (day) {case 1:System.out.println("星期一");break;case 2:System.out.println("星期二");break;case 3:System.out.println("星期三");break;default:System.out.println("其他");
}

5.2 循环语句

for 循环

for 循环用于执行指定次数的循环。

for (int i = 0; i < 5; i++) {System.out.println(i);
}

while 循环

while 循环在条件为真时重复执行代码块。

int j = 0;
while (j < 5) {System.out.println(j);j++;
}

do - while 循环

do - while 循环先执行一次代码块,然后再判断条件是否为真,如果为真则继续执行循环。

int k = 0;
do {System.out.println(k);k++;
} while (k < 5);

5.3 跳转语句

break 语句

break 语句用于跳出当前所在的循环或 switch 语句。

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 == 5) {continue;}System.out.println(i);
}

return 语句

return 语句用于从方法中返回值并结束方法的执行。

public int add(int a, int b) {return a + b;
}

六、面向对象编程

6.1 类和对象

类是对象的抽象,定义了对象的属性和方法。类的定义格式为:

class 类名 {// 成员变量(属性)数据类型 变量名;// 构造方法类名() {// 构造方法体}// 成员方法(行为)返回类型 方法名(参数列表) {// 方法体return 返回值;}
}

对象

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

class Person {String name;int age;void speak() {System.out.println("My name is " + name + ", I'm " + age + " years old.");}
}public class Main {public static void main(String[] args) {// 创建对象Person p = new Person();// 给对象的属性赋值p.name = "John";p.age = 20;// 调用对象的方法p.speak();}
}

6.2 封装

封装是将对象的属性和方法隐藏起来,只对外提供公共的访问方式,提高了代码的安全性和可维护性。在 Java 中,可以使用访问修饰符来实现封装。

访问修饰符 本类 同一个包中的类 不同包中的子类 不同包中的非子类
private 可以访问 不可以访问 不可以访问 不可以访问
default 可以访问 可以访问 不可以访问 不可以访问
protected 可以访问 可以访问 可以访问 不可以访问
public 可以访问 可以访问 可以访问 可以访问
class Student {private String name;private int age;// 公共的访问方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {if (age > 0) {this.age = age;}}
}

6.3 继承

继承是指一个类可以继承另一个类的属性和方法,提高了代码的复用性。被继承的类称为父类(基类),继承的类称为子类(派生类)。Java 中使用 extends 关键字实现继承。

class Animal {void eat() {System.out.println("Animal is eating.");}
}class Dog extends Animal {void bark() {System.out.println("Dog is barking.");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.eat(); // 调用父类的方法dog.bark(); // 调用子类的方法}
}

6.4 多态

多态是指同一个方法可以根据对象的不同类型表现出不同的行为,包括方法重载和方法重写。

方法重载

方法重载是指在同一个类中,方法名相同但参数列表不同的多个方法。方法重载的判断依据是方法的参数类型、参数个数或参数顺序不同。

class Calculator {int add(int a, int b) {return a + b;}int add(int a, int b, int c) {return a + b + c;}double add(double a, double b) {return a + b;}
}

方法重写

方法重写是指在子类中重写父类的方法,方法名、参数

继续生成未生成的内容

列表和返回值类型都必须与父类方法相同,并且可以使用@Override注解来确保重写的正确性。方法重写体现了运行时多态。

class Animal {void sound() {System.out.println("Animal makes a sound.");}
}class Cat extends Animal {@Overridevoid sound() {System.out.println("Cat meows.");}
}class Dog extends Animal {@Overridevoid sound() {System.out.println("Dog barks.");}
}public class Main {public static void main(String[] args) {Animal cat = new Cat();Animal dog = new Dog();cat.sound(); // 输出 "Cat meows."dog.sound(); // 输出 "Dog barks."}
}

6.5 抽象类和接口

抽象类

抽象类是使用abstract关键字修饰的类,抽象类不能被实例化,主要用于作为其他类的基类。抽象类中可以包含抽象方法和具体方法。抽象方法是使用abstract关键字修饰的方法,只有方法声明,没有方法体,子类必须实现抽象类中的所有抽象方法。

abstract class Shape {abstract double area(); // 抽象方法void printInfo() {System.out.println("This is a shape.");}
}class Circle extends Shape {private double radius;public Circle(double radius) {this.radius = radius;}@Overridedouble area() {return Math.PI * radius * radius;}
}

接口

接口是一种特殊的抽象类型,使用interface关键字定义。接口中只能包含抽象方法和常量(默认使用public static final修饰)。类通过implements关键字实现接口,一个类可以实现多个接口。

interface Flyable {void fly();
}interface Swimmable {void swim();
}class Duck implements Flyable, Swimmable {@Overridepublic void fly() {System.out.println("Duck is flying.");}@Overridepublic void swim() {System.out.println("Duck is swimming.");}
}

6.6 内部类

内部类是定义在另一个类内部的类,根据定义位置和修饰符的不同,内部类可以分为成员内部类、局部内部类、静态内部类和匿名内部类。

成员内部类

成员内部类是定义在类的成员位置的类,它可以访问外部类的所有成员。

class Outer {private int outerField = 10;class Inner {void printOuterField() {System.out.println(outerField);}}
}public class Main {public static void main(String[] args) {Outer outer = new Outer();Outer.Inner inner = outer.new Inner();inner.printOuterField();}
}

局部内部类

局部内部类是定义在方法或代码块内部的类,它只能在定义它的方法或代码块内部使用。

class Outer {void outerMethod() {class LocalInner {void printMessage() {System.out.println("This is a local inner class.");}}LocalInner localInner = new LocalInner();localInner.printMessage();}
}

静态内部类

静态内部类是使用static关键字修饰的内部类,它只能访问外部类的静态成员。

class Outer {private static int outerStaticField = 20;static class StaticInner {void printOuterStaticField() {System.out.println(outerStaticField);}}
}public class Main {public static void main(String[] args) {Outer.StaticInner staticInner = new Outer.StaticInner();staticInner.printOuterStaticField();}
}

匿名内部类

匿名内部类是一种没有显式类名的内部类,通常用于创建一次性的对象。

interface MyInterface {void doSomething();
}public class Main {public static void main(String[] args) {MyInterface obj = new MyInterface() {@Overridepublic void doSomething() {System.out.println("Doing something...");}};obj.doSomething();}
}

七、异常处理

7.1 异常概述

异常是指程序在运行过程中出现的错误或意外情况,Java 提供了异常处理机制来捕获和处理这些异常,保证程序的健壮性。异常类都继承自Throwable类,Throwable类有两个子类:ErrorException

  • Error:表示系统级的错误,通常是由 JVM 或硬件问题引起的,程序无法处理,如OutOfMemoryErrorStackOverflowError等。
  • Exception:表示程序可以处理的异常,又分为受检查异常(Checked Exception)和运行时异常(Runtime Exception)。

7.2 异常分类

受检查异常(Checked Exception)

受检查异常是指在编译时必须进行捕获或声明抛出的异常,如IOExceptionSQLException等。如果不处理受检查异常,程序将无法通过编译。

运行时异常(Runtime Exception)

运行时异常是指在编译时不需要进行捕获或声明抛出的异常,通常是由程序逻辑错误引起的,如NullPointerExceptionArrayIndexOutOfBoundsException等。

7.3 异常处理语句

try - catch 语句

try - catch语句用于捕获和处理异常。try块中包含可能会抛出异常的代码,catch块用于捕获并处理相应类型的异常。

try {int[] arr = new int[5];System.out.println(arr[10]); // 可能会抛出 ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常: " + e.getMessage());
}

try - catch - finally 语句

finally块中的代码无论是否发生异常都会执行,通常用于释放资源,如关闭文件、数据库连接等。

try {int[] arr = new int[5];System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常: " + e.getMessage());
} finally {System.out.println("无论是否发生异常,finally 块都会执行。");
}

throws 关键字

throws关键字用于声明方法可能会抛出的异常,调用该方法的代码必须处理这些异常。

public void readFile() throws java.io.IOException {java.io.FileReader fr = new java.io.FileReader("test.txt");// 读取文件的代码fr.close();
}

throw 关键字

throw关键字用于手动抛出异常,通常在方法内部使用。

public void checkAge(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数。");}
}

7.4 自定义异常

在 Java 中,我们可以通过继承ExceptionRuntimeException类来创建自定义异常。

class MyException extends Exception {public MyException(String message) {super(message);}
}public class Main {public static void main(String[] args) {try {throw new MyException("这是一个自定义异常。");} catch (MyException e) {System.out.println(e.getMessage());}}
}

八、数组

8.1 数组定义

数组是一种存储相同类型数据的容器,数组的长度在创建时确定,并且不能改变。数组的定义方式有以下几种:

// 声明数组
int[] arr1;
// 创建数组
arr1 = new int[5];// 声明并创建数组
int[] arr2 = new int[5];// 声明、创建并初始化数组
int[] arr3 = {1, 2, 3, 4, 5};

8.2 数组访问

通过下标访问数组元素,下标从 0 开始,最大下标为数组长度减 1。

int[] arr = {1, 2, 3, 4, 5};
// 访问数组元素
int num = arr[2]; // 访问下标为 2 的元素,值为 3
// 修改数组元素
arr[3] = 10;

8.3 多维数组

多维数组是数组的数组,常见的有二维数组。

// 声明并创建二维数组
int[][] matrix = new int[3][4];// 声明、创建并初始化二维数组
int[][] matrix2 = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};// 访问二维数组元素
int element = matrix2[1][2]; // 访问第 2 行第 3 列的元素,值为 7

8.4 数组常用操作

遍历数组

int[] arr = {1, 2, 3, 4, 5};
// 使用 for 循环遍历数组
for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);
}// 使用增强 for 循环遍历数组
for (int num : arr) {System.out.println(num);
}

数组排序

import java.util.Arrays;int[] arr = {5, 3, 1, 4, 2};
// 使用 Arrays 类的 sort 方法对数组进行排序
Arrays.sort(arr);
for (int num : arr) {System.out.println(num);
}

九、集合框架

9.1 集合概述

集合是 Java 中用于存储和操作一组对象的容器,与数组相比,集合的长度可以动态变化。Java 集合框架主要分为CollectionMap两大接口。

9.2 Collection 接口

Collection接口是所有集合类的根接口,它有两个重要的子接口:ListSet

List 接口

List接口表示有序、可重复的集合,常见的实现类有ArrayListLinkedList

import java.util.ArrayList;
import java.util.List;// 创建 ArrayList 对象
List<String> list = new ArrayList<>();
// 添加元素
list.add("apple");
list.add("banana");
// 访问元素
String element = list.get(0);
// 遍历列表
for (String item : list) {System.out.println(item);
}

Set 接口

Set接口表示无序、不可重复的集合,常见的实现类有HashSetTreeSet

import java.util.HashSet;
import java.util.Set;// 创建 HashSet 对象
Set<String> set = new HashSet<>();
// 添加元素
set.add("apple");
set.add("banana");
// 遍历集合
for (String item : set) {System.out.println(item);
}

9.3 Map 接口

Map接口用于存储键值对,键不可重复,常见的实现类有HashMapTreeMap

import java.util.HashMap;
import java.util.Map;// 创建 HashMap 对象
Map<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("one", 1);
map.put("two", 2);
// 获取值
int value = map.get("one");
// 遍历 Map
for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}

9.4 集合的常用方法

  • 添加元素add()put()
  • 删除元素remove()
  • 判断元素是否存在contains()
  • 获取集合大小size()
  • 清空集合clear()

十、输入输出流

10.1 流的分类

  • 按方向分:输入流和输出流。输入流用于从数据源读取数据,输出流用于向目的地写入数据。
  • 按处理数据单位分:字节流和字符流。字节流以字节为单位处理数据,字符流以字符为单位处理数据。

10.2 字节流

字节流的抽象基类是InputStreamOutputStream。常见的字节流类有FileInputStreamFileOutputStream等。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("input.txt");FileOutputStream fos = new FileOutputStream("output.txt")) {int c;while ((c = fis.read()) != -1) {fos.write(c);}} catch (IOException e) {e.printStackTrace();}}
}

10.3 字符流

字符流的抽象基类是ReaderWriter。常见的字符流类有FileReaderFileWriter等。

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class CharacterStreamExample {public static void main(String[] args) {try (FileReader fr = new FileReader("input.txt");FileWriter fw = new FileWriter("output.txt")) {int c;while ((c = fr.read()) != -1) {fw.write(c);}} catch (IOException e) {e.printStackTrace();}}
}

10.4 缓冲流

缓冲流是对字节流和字符流的包装,提供了缓冲功能,提高了读写效率。常见的缓冲流类有BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter等。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class BufferedStreamExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine();}} catch (IOException e) {e.printStackTrace();}}
}

10.5 对象序列化和反序列化

对象序列化是指将对象转换为字节序列的过程,反序列化是指将字节序列转换为对象的过程。要实现对象序列化,类必须实现Serializable接口。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;class Person implements Serializable {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}public class SerializationExample {public static void main(String[] args) {// 序列化try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {Person person = new Person("John", 20);oos.writeObject(person);} catch (IOException e) {e.printStackTrace();}// 反序列化try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {Person person = (Person) ois.readObject();System.out.println("Name: " + person.getName() + ", Age: " + person.getAge());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

十一、多线程

11.1 线程概述

线程是程序执行的最小单位,一个进程可以包含多个线程。多线程可以提高程序的并发性能,使得程序可以同时执行多个任务。

11.2 创建线程的方式

继承 Thread 类

class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": " + i);}}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}

实现 Runnable 接口

class MyRunnable implements Runnable {@Overridepublic void run() {for

继续生成未生成的内容

11.2 创建线程的方式(续)

实现 Callable 接口

Callable 接口与 Runnable 接口类似,但 Callablecall() 方法可以有返回值,并且可以抛出异常。通常需要结合 FutureTask 类来获取返回值。

import java.util.concurrent.*;class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i <= 10; i++) {sum += i;}return sum;}
}public class CallableExample {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable callable = new MyCallable();FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread thread = new Thread(futureTask);thread.start();// 获取线程执行结果Integer result = futureTask.get();System.out.println("线程执行结果: " + result);}
}

11.3 线程的生命周期

线程的生命周期包含以下几个状态:

  • 新建(New):当创建一个 Thread 对象时,线程处于新建状态。
Thread thread = new Thread(() -> System.out.println("Hello"));
  • 就绪(Runnable):调用 start() 方法后,线程进入就绪状态,等待 CPU 调度执行。
thread.start();
  • 运行(Running):当 CPU 调度该线程时,线程进入运行状态,执行 run() 方法中的代码。
  • 阻塞(Blocked):线程在某些情况下会进入阻塞状态,如等待 I/O 操作、获取锁失败等。当阻塞条件解除后,线程会重新进入就绪状态。
  • 等待(Waiting):线程调用 wait()join()LockSupport.park() 方法后会进入等待状态,需要其他线程进行相应的唤醒操作。
  • 计时等待(Timed Waiting):线程调用 sleep(long millis)wait(long timeout)join(long millis) 等带有时间参数的方法后会进入计时等待状态,当时间到期或被其他线程唤醒时,线程会重新进入就绪状态。
  • 终止(Terminated):线程的 run() 方法执行完毕或因异常退出时,线程进入终止状态。

11.4 线程同步

多个线程同时访问共享资源时可能会出现数据不一致的问题,需要进行线程同步来保证数据的一致性和完整性。

synchronized 关键字

  • 同步方法:使用 synchronized 修饰方法,同一时间只有一个线程可以访问该方法。
class Counter {private int count = 0;public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
}
  • 同步代码块:使用 synchronized 关键字指定同步的对象,同一时间只有一个线程可以访问该同步代码块。
class Counter {private int count = 0;private final Object lock = new Object();public void increment() {synchronized (lock) {count++;}}public int getCount() {synchronized (lock) {return count;}}
}

Lock 接口

Lock 接口提供了比 synchronized 更灵活的锁机制,常见的实现类有 ReentrantLock

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class Counter {private int count = 0;private final 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();}}
}

11.5 线程通信

线程通信是指多个线程之间通过某种机制进行信息交换和协调工作,常见的方法有 wait()notify()notifyAll()

class Message {private String content;private boolean available = false;public synchronized String read() {while (!available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}available = false;notifyAll();return content;}public synchronized void write(String content) {while (available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}this.content = content;available = true;notifyAll();}
}public class ThreadCommunicationExample {public static void main(String[] args) {Message message = new Message();new Thread(() -> {message.write("Hello, World!");}).start();new Thread(() -> {System.out.println(message.read());}).start();}
}

十二、反射

12.1 反射概述

反射是指在运行时动态获取类的信息并操作类的属性和方法的机制。通过反射,我们可以在运行时创建对象、调用方法、访问属性等,提高了程序的灵活性和可扩展性。

12.2 反射的基本操作

获取 Class 对象

  • 通过类名的 class 属性
Class<?> clazz1 = String.class;
  • 通过对象的 getClass() 方法
String str = "Hello";
Class<?> clazz2 = str.getClass();
  • 通过 Class.forName() 方法
try {Class<?> clazz3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {e.printStackTrace();
}

创建对象

try {Class<?> clazz = Class.forName("java.util.ArrayList");Object obj = clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {e.printStackTrace();
}

调用方法

import java.lang.reflect.Method;class MyClass {public void sayHello() {System.out.println("Hello!");}
}public class ReflectionMethodExample {public static void main(String[] args) throws Exception {Class<?> clazz = MyClass.class;Object obj = clazz.getDeclaredConstructor().newInstance();Method method = clazz.getMethod("sayHello");method.invoke(obj);}
}

访问属性

import java.lang.reflect.Field;class MyClass {private String name = "John";
}public class ReflectionFieldExample {public static void main(String[] args) throws Exception {Class<?> clazz = MyClass.class;Object obj = clazz.getDeclaredConstructor().newInstance();Field field = clazz.getDeclaredField("name");field.setAccessible(true);String value = (String) field.get(obj);System.out.println(value);}
}

12.3 反射的优缺点

优点

  • 灵活性高:可以在运行时动态地创建对象、调用方法和访问属性,提高了程序的灵活性。
  • 可扩展性强:可以通过反射实现插件化开发,方便地扩展程序的功能。

缺点

  • 性能开销大:反射涉及到动态解析和调用,会比直接调用方法和访问属性的性能低。
  • 安全性问题:反射可以访问和修改类的私有成员,可能会破坏类的封装性和安全性。

十三、注解

13.1 注解概述

注解(Annotation)是 Java 5 引入的一种元数据机制,它可以为程序元素(类、方法、字段等)添加额外的信息,这些信息可以在编译时、运行时被读取和处理。

13.2 内置注解

Java 提供了一些内置注解,常见的有:

  • @Override:用于标记方法是重写父类的方法,如果不符合重写规则,编译器会报错。
class Parent {public void print() {System.out.println("Parent");}
}class Child extends Parent {@Overridepublic void print() {System.out.println("Child");}
}
  • @Deprecated:用于标记某个元素(类、方法等)已经过时,不建议使用。
@Deprecated
public void oldMethod() {// 旧方法的实现
}
  • @SuppressWarnings:用于抑制编译器的警告信息。
@SuppressWarnings("unchecked")
List list = new ArrayList();

13.3 自定义注解

自定义注解使用 @interface 关键字定义,注解中可以定义成员变量。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {String value() default "";
}// 使用注解
class MyClass {@MyAnnotation("Hello")public void myMethod() {// 方法实现}
}

13.4 注解处理器

注解处理器可以在编译时或运行时读取和处理注解信息。以下是一个简单的运行时注解处理器示例:

import java.lang.reflect.Method;public class AnnotationProcessor {public static void processAnnotations(Object obj) throws Exception {Class<?> clazz = obj.getClass();Method[] methods = clazz.getMethods();for (Method method : methods) {if (method.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);System.out.println("Annotation value: " + annotation.value());method.invoke(obj);}}}public static void main(String[] args) throws Exception {MyClass myClass = new MyClass();processAnnotations(myClass);}
}

十四、泛型

14.1 泛型概述

泛型是 Java 5 引入的一种类型参数化机制,它允许在定义类、接口和方法时使用类型参数,使得代码可以处理不同类型的数据,提高了代码的复用性和类型安全性。

14.2 泛型类

class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
}public class GenericClassExample {public static void main(String[] args) {Box<String> stringBox = new Box<>();stringBox.setContent("Hello");String str = stringBox.getContent();System.out.println(str);}
}

14.3 泛型接口

interface Generator<T> {T generate();
}class IntegerGenerator implements Generator<Integer> {@Overridepublic Integer generate() {return (int) (Math.random() * 100);}
}public class GenericInterfaceExample {public static void main(String[] args) {Generator<Integer> generator = new IntegerGenerator();Integer num = generator.generate();System.out.println(num);}
}

14.4 泛型方法

class GenericMethods {public <T> void printArray(T[] array) {for (T element : array) {System.out.print(element + " ");}System.out.println();}
}public class GenericMethodExample {public static void main(String[] args) {GenericMethods gm = new GenericMethods();Integer[] intArray = {1, 2, 3};String[] strArray = {"Hello", "World"};gm.printArray(intArray);gm.printArray(strArray);}
}

14.5 泛型的通配符

  • ? extends T:表示上界通配符,即泛型类型必须是 TT 的子类。
  • ? super T:表示下界通配符,即泛型类型必须是 TT 的父类。
import java.util.ArrayList;
import java.util.List;class Animal {}
class Dog extends Animal {}public class WildcardExample {public static void printAnimals(List<? extends Animal> animals) {for (Animal animal : animals) {System.out.println(animal);}}public static void addDog(List<? super Dog> dogs) {dogs.add(new Dog());}public static void main(String[] args) {List<Dog> dogList = new ArrayList<>();printAnimals(dogList);addDog(dogList);}
}

继续生成未生成的内容

十五、枚举类型

15.1 枚举概述

枚举类型(enum)是 Java 5 引入的一种特殊类,用于定义一组固定的常量。枚举类型可以使代码更具可读性和可维护性,同时避免了使用普通常量可能带来的错误。

15.2 枚举的基本定义和使用

// 定义一个表示星期的枚举类型
enum Weekday {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}public class EnumExample {public static void main(String[] args) {// 使用枚举常量Weekday today = Weekday.MONDAY;System.out.println("Today is " + today);// 遍历枚举常量for (Weekday day : Weekday.values()) {System.out.println(day);}}
}

15.3 枚举的属性和方法

枚举类型可以有自己的属性和方法,类似于普通类。

enum Color {RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255);private int red;private int green;private int blue;// 构造方法Color(int red, int green, int blue) {this.red = red;this.green = green;this.blue = blue;}// 获取 RGB 值的方法public String getRGB() {return "RGB: (" + red + ", " + green + ", " + blue + ")";}
}public class EnumWithPropertiesExample {public static void main(String[] args) {Color color = Color.RED;System.out.println(color.getRGB());}
}

15.4 枚举的 switch 语句

枚举类型非常适合在 switch 语句中使用,能使代码更加清晰。

enum Season {SPRING, SUMMER, AUTUMN, WINTER
}public class EnumSwitchExample {public static void main(String[] args) {Season currentSeason = Season.SPRING;switch (currentSeason) {case SPRING:System.out.println("It's spring, flowers are blooming.");break;case SUMMER:System.out.println("It's summer, it's very hot.");break;case AUTUMN:System.out.println("It's autumn, leaves are falling.");break;case WINTER:System.out.println("It's winter, it's cold outside.");break;}}
}

十六、字符串处理

16.1 String

String 类是 Java 中用于处理字符串的常用类,它是不可变的,即一旦创建,其值不能被改变。

// 创建字符串对象
String str1 = "Hello";
String str2 = new String("World");// 字符串拼接
String str3 = str1 + " " + str2;
System.out.println(str3);// 获取字符串长度
int length = str3.length();
System.out.println("Length: " + length);// 字符串比较
boolean isEqual = str1.equals("Hello");
System.out.println("Is equal: " + isEqual);// 字符串查找
int index = str3.indexOf("World");
System.out.println("Index of 'World': " + index);

16.2 StringBuilderStringBuffer

由于 String 类是不可变的,频繁拼接字符串会产生大量的临时对象,影响性能。StringBuilderStringBuffer 是可变的字符串序列,用于高效地拼接字符串。

StringBuilder

StringBuilder 是非线程安全的,性能较高,适用于单线程环境。

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
System.out.println(result);

StringBuffer

StringBuffer 是线程安全的,性能相对较低,适用于多线程环境。

StringBuffer sbf = new StringBuffer();
sbf.append("Hello");
sbf.append(" ");
sbf.append("World");
String result2 = sbf.toString();
System.out.println(result2);

16.3 字符串格式化

Java 提供了 String.format() 方法和 Formatter 类用于字符串格式化。

// 使用 String.format() 方法
String name = "John";
int age = 20;
String formatted = String.format("My name is %s and I'm %d years old.", name, age);
System.out.println(formatted);// 使用 Formatter 类
import java.util.Formatter;
Formatter formatter = new Formatter();
formatter.format("The price is %.2f dollars.", 9.99);
System.out.println(formatter.toString());
formatter.close();

16.4 字符串分割和替换

// 字符串分割
String str = "apple,banana,orange";
String[] fruits = str.split(",");
for (String fruit : fruits) {System.out.println(fruit);
}// 字符串替换
String replaced = str.replace("apple", "grape");
System.out.println(replaced);

十七、日期和时间处理

17.1 旧的日期和时间 API(Java 8 之前)

Date

Date 类用于表示特定的瞬间,精确到毫秒。

import java.util.Date;Date now = new Date();
System.out.println("Current date: " + now);

SimpleDateFormat

SimpleDateFormat 类用于格式化和解析日期字符串。

import java.text.SimpleDateFormat;
import java.util.Date;Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formattedDate = sdf.format(date);
System.out.println("Formatted date: " + formattedDate);try {Date parsedDate = sdf.parse("2023-10-01 12:00:00");System.out.println("Parsed date: " + parsedDate);
} catch (Exception e) {e.printStackTrace();
}

17.2 新的日期和时间 API(Java 8 及以后)

Java 8 引入了新的日期和时间 API,位于 java.time 包下,提供了更丰富、更易用的日期和时间处理功能。

LocalDateLocalTimeLocalDateTime

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;// 获取当前日期
LocalDate currentDate = LocalDate.now();
System.out.println("Current date: " + currentDate);// 获取当前时间
LocalTime currentTime = LocalTime.now();
System.out.println("Current time: " + currentTime);// 获取当前日期和时间
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("Current date and time: " + currentDateTime);

DateTimeFormatter

DateTimeFormatter 类用于格式化和解析日期时间对象。

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);
System.out.println("Formatted date and time: " + formatted);LocalDateTime parsedDateTime = LocalDateTime.parse("2023-10-01 12:00:00", formatter);
System.out.println("Parsed date and time: " + parsedDateTime);

DurationPeriod

Duration 用于表示两个时间点之间的时长,Period 用于表示两个日期之间的时间段。

import java.time.Duration;
import java.time.LocalTime;
import java.time.Period;
import java.time.LocalDate;// 使用 Duration
LocalTime start = LocalTime.of(10, 0);
LocalTime end = LocalTime.of(12, 30);
Duration duration = Duration.between(start, end);
System.out.println("Duration: " + duration.toMinutes() + " minutes");// 使用 Period
LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);
Period period = Period.between(startDate, endDate);
System.out.println("Period: " + period.getMonths() + " months and " + period.getDays() + " days");

十八、正则表达式

18.1 正则表达式概述

正则表达式是一种用于描述字符串模式的工具,通过特定的字符和语法规则,可以方便地进行字符串的匹配、查找、替换等操作。

18.2 正则表达式的基本语法

  • 字符类[abc] 表示匹配 abc 中的任意一个字符;[^abc] 表示匹配除 abc 之外的任意一个字符。
  • 预定义字符类. 表示匹配任意一个字符;\d 表示匹配一个数字字符,等价于 [0-9]\w 表示匹配一个单词字符,等价于 [a-zA-Z_0-9]
  • 数量词* 表示匹配前面的元素零次或多次;+ 表示匹配前面的元素一次或多次;? 表示匹配前面的元素零次或一次。

18.3 Java 中使用正则表达式

import java.util.regex.Matcher;
import java.util.regex.Pattern;// 定义正则表达式
String regex = "\\d+";
// 编译正则表达式
Pattern pattern = Pattern.compile(regex);
// 创建 Matcher 对象
Matcher matcher = pattern.matcher("There are 123 apples.");// 查找匹配的字符串
while (matcher.find()) {System.out.println("Found: " + matcher.group());
}// 替换匹配的字符串
String replaced = pattern.matcher("There are 123 apples.").replaceAll("XXX");
System.out.println("Replaced: " + replaced);

十九、文件和目录操作

19.1 File

File 类用于表示文件和目录的抽象路径名,可以进行文件和目录的创建、删除、重命名等操作。

import java.io.File;// 创建 File 对象
File file = new File("test.txt");// 判断文件是否存在
if (file.exists()) {System.out.println("File exists.");
} else {try {// 创建新文件boolean created = file.createNewFile();if (created) {System.out.println("File created.");}} catch (Exception e) {e.printStackTrace();}
}// 删除文件
boolean deleted = file.delete();
if (deleted) {System.out.println("File deleted.");
}// 操作目录
File dir = new File("mydir");
if (!dir.exists()) {// 创建目录boolean dirCreated = dir.mkdir();if (dirCreated) {System.out.println("Directory created.");}
}// 列出目录下的文件和子目录
File[] files = dir.listFiles();
if (files != null) {for (File f : files) {System.out.println(f.getName());}
}

19.2 PathPaths 类(Java 7 及以后)

Java 7 引入了 java.nio.file 包,提供了更强大的文件和目录操作功能,PathPaths 是其中的重要类。

import java.nio.file.Path;
import java.nio.file.Paths;// 创建 Path 对象
Path path = Paths.get("test.txt");
System.out.println("Path: " + path);// 获取文件名
String fileName = path.getFileName().toString();
System.out.println("File name: " + fileName);// 获取父目录
Path parent = path.getParent();
if (parent != null) {System.out.println("Parent directory: " + parent);
}

19.3 文件复制和移动

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;public class FileCopyMoveExample {public static void main(String[] args) {Path source = Paths.get("source.txt");Path destination = Paths.get("destination.txt");try {// 复制文件Files.copy(source, destination);System.out.println("File copied.");// 移动文件Files.move(destination, Paths.get("newdestination.txt"));System.out.println("File moved.");} catch (IOException e) {e.printStackTrace();}}
}

以上涵盖了 Java 基础知识的主要方面,在实际开发中,这些知识是进一步学习和应用 Java 高级特性的基础。

还有吗,有的话继续列出来,只要java基础知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/882367.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

容器附加存储CAS之OpenEBS快速入门

作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 目录一.CAS之OpenEBS存储机制概述1.什么是CAS2.什么是OpenEBS3.OpenEBS数据引擎4.NDM(Node Disk Manager)5.部署OpenEBS的基本流程二.部署OpenEBS 一.CAS之OpenEBS存储机制概述 1.什么是CAS Kubernetes的卷…

【CodeForces训练记录】Codeforces Round 1004 (Div. 2)

训练情况赛后反思 这场太神奇了,都在和出题人对脑电波,全是智慧题 A题 我们考虑进位的情况,例如 9999 之类的,我们发现进位对答案的影响只有 \(x - 9k + 1 = y\),判断 \(k\) 是否存在非负整数解即可点击查看代码 #include <bits/stdc++.h> // #define int long long…

短信验证码爆破

漏洞原理 短信验证码验证时间和次数无限制,存在爆破可能 短信验证码有效期:5~10min,验证码位数4位或6位,纯数字 破解方式:使用枚举逐个尝试 使用BP爆破短信验证码可以先用已有手机号确认验证码位数2.发送验证码后将验证码输入,然后登陆抓包后续和爆破操作一致如果字典太大…

【洛谷P1955】程序自动分析[NOI2015]

今天开始学习并查集 什么是并查集呢?顾名思义,就是动态维护一个方便进行合并和查找的集合 我们采用的是树状结构 也就是说,对于一开始的每个元素 它的爸爸是它自己 然后在输入两个元素的从属关系的时候,通过路径压缩,把它的爸爸直接连到根节点 因为我们只关心这个元素在这…

chorme 系统代理设置

https 需要证书 1.使用BurpSuite导出CA证书,文件导出到本地2. 谷歌浏览器添加证书 谷歌浏览器->设置->搜索"证书"->安全->管理证书->管理从windows导入的证书->受信任的根证书颁发机构->导入第一步的证书3.设置系统代理 windows系统->设置-…

picachu 越权漏洞

1. 水平越权 1.查看提示信息,提供了3个普通用户2. 登陆其中一个账户,并查看个人信息3.根据url 可以看出有用户名信息,尝试在URL中更改其他账户名,发现查看到其他用户的信息4.再次点击查看个人信息按钮,信息更改为已登陆的用户的信息5. 查看源代码发现第27行username 的值是…

windows使用Makefile时自动给可执行文件加上.exe后缀

APP := main在使用makefile的时候,一般通过变量设置自己想要编译出来的可执行文件的名字在windows平台编译出来的可执行文件是需要.exe后缀的识别当前操作系统 通过识别当前的操作系统是什么,从而确定是否添加这个后缀在windows系统中,有这个环境变量说明自己的系统是windows而…

pikachu 验证码绕过 onclient

前端生成的验证码,无论验证码是否正确,都不影响发送到服务器结果(刷新验证码不会通过BP,没有对应的请求出现) 前端验证码逻辑:输入账号密码验证码,如果验证码正确,数据将发送给服务器;如果验证码不正确,数据不会发送给服务器 1.查看页面源代码,发现是前端生成验证码…

图片验证码绕过(验证码不失效) - 使用验证码识别插件

使用BP抓包,抓到的包没有验证码请求添加过滤图片,出现图片验证码请求包添加captcha-killer-modified 插件,识别图片验证码验证码识别服务按照下面链接操作 https://www.cnblogs.com/mr-ryan/p/17812482.html 文档中的ocr_api_server 使用这个链接:https://gitee.com/yijing…

弱口令暴力破解

使用vulhub/tomcat/tomcat8 靶场点击Manager App按钮,提示登陆,输入用户名密码通过BP抓取提交用户名密码的请求报文,获取Authorization信息将Authorization 发送到解码器解码 ,使用Base64 解码成功(一般Base64 编码最后会带= 或者 ==), 解码后知道了发送的密码规则添加Aut…

攻防世界-RE-CatFly

我们将文件拖入虚拟机中运行看到这样的效果 其中上方的数字是不停变化的,下面的次数也在不断的增长。我们猜测这两者是有关联的。 接下来我们进行反编译程序的分析。最上面的字符输出肯定是与printf函数有关,所以我们检索printf在main函数中的调用time(&timer);v13 = 1;v…

Maui 内嵌网页直接调用本机原生功能 Demo

使用 MAUI 制作 H5 套壳程序有以下几个好处:跨平台支持:MAUI (Multi-platform App UI) 允许开发者在多个平台(如 iOS、Android、Windows 和 macOS)上运行应用程序。统一封装的MauiPlus库可以统一调用本机功能,确保在不同平台上有一致的用户体验。访问本地功能:MauiPlus库…