java基础知识【java核心类】

万物都是相同的,只要你把一个能力掌握好了,你会发现其他的东西都是万变不离其宗。

面向对象基础

模块

一、模块的核心概念

  1. 解决依赖问题

    • Java 9 前:jar包仅作为 class 文件的容器,不管理依赖,需手动通过-cp指定依赖,易引发ClassNotFoundException
    • Java 9 后:模块是自带依赖关系的 class 容器 ,通过module-info.class声明依赖,确保编译和运行时自动定位依赖模块。
  2. JDK 标准库模块化

    • rt.jar被拆分为数十个.jmod模块(如java.base.jmod),位于$JAVA_HOME/jmods,所有模块直接或间接依赖根模块java.base
    • 模块支持多版本和 JNI 二进制扩展,比 jar 包功能更强大。

二、编写模块

  1. 模块描述文件module-info.java

    • 声明模块名(如module hello.world)和依赖(requires java.xml),默认依赖java.base可省略。
    • 可通过exports 包名导出包,供其他模块访问(模块内权限控制增强,未导出的包对外不可见)。
  2. 编译与打包

    • 编译:javac -d bin src/module-info.java src/...,生成module-info.class
    • 打包为可运行 jar:jar --create --file hello.jar --main-class 主类 -C bin .
    • 转为模块文件(.jmod):jmod create --class-path hello.jar hello.jmod(主要用于打包 JRE)。

三、运行模块与打包 JRE

  1. 运行模块

    • 使用--module-path指定模块路径,--module指定模块名:

      bash

      arduino 复制代码
      java --module-path hello.jar --module hello.world
    • .jmod文件不能直接运行,需通过jlink工具处理。

  2. 精简 JRE 打包(jlink)

    • 按需提取所需模块(包括自定义模块),生成轻量 JRE,减少分发体积:

      bash

      css 复制代码
      jlink --module-path hello.jmod --add-modules java.base,java.xml,hello.world --output jre/
    • 分发时只需包含该jre目录,无需完整 JDK。

四、模块的访问权限

  • 模块内权限:继承 Java 原有的 public/protected/private/ 包访问权限,但仅在模块内有效。
  • 模块间访问 :需通过exports 包名显式导出包,否则其他模块无法访问该包内的类(如java.xml模块导出java.xml包后,外部才能使用其中的类)。

五、核心优势与小结

  • 依赖管理:模块显式声明依赖,避免手动配置 classpath 的繁琐和错误。
  • JRE 瘦身 :通过jlink按需打包,大幅减小运行时环境体积,方便部署。
  • 代码隔离:导出机制增强了模块间的封装性,提升系统安全性和可维护性。

java核心类

字符串和编码

一、String 基础特性与不可变性
  1. 本质与创建

    • String 是引用类型,底层通过 char[](早期 JDK)或优化的byte[](新版本,存储 ASCII 字符时节省空间)存储,支持字面量"..."和构造函数new String(char[])创建。
    • 不可变性 :内部字段private final修饰,所有修改操作(如toUpperCase())均返回新字符串,原字符串不变。
二、字符串比较规则
  1. 内容 vs 引用

    • equals() :比较字符串内容是否相同(需忽略大小写时用equalsIgnoreCase())。
    • == :仅比较引用是否指向同一对象(常量池优化可能导致==true,但属特例,不可依赖)。
    • 示例new String("a") == "a"false,因前者在堆中,后者在常量池。
三、常用操作方法详解
  1. 子串与搜索

    • 包含:contains(CharSequence);索引:indexOf()/lastIndexOf();首尾匹配:startsWith()/endsWith()
    • 提取:substring(start, end)(左闭右开,索引从 0 开始)。
  2. 空白处理

    • trim():移除首尾空格、\t、\r、\nstrip():额外处理全角空格\u3000isEmpty()(长度为 0)与isBlank()(全空白)。
  3. 替换与分割

    • 普通替换:replace(char/CharSequence);正则替换:replaceAll(String regex, String replacement)(如replaceAll("[\,\;\s]+", ","))。
    • 分割:split(String regex)(传入正则,如split("\,")按逗号分割,注意正则元字符需转义,如.需写为\.)。
  4. 拼接与格式化

    • 拼接:String.join(separator, array)(高效,避免+操作的性能损耗)。
    • 格式化:formatted()String.format(),占位符%s(字符串)、%d(整数)、%.2f(两位小数浮点数)等。
  5. 类型转换

    • 转字符串:String.valueOf()(自动适配类型);转基本类型:Integer.parseInt()/Boolean.parseBoolean()(注意getInteger()获取系统变量)。
四、字符编码原理与 Java 实现
  1. 编码基础

    • ASCII:1 字节(0-127),仅英文字符。
    • Unicode :统一编码(2 字节或更多),解决多语言冲突(如中文'中'的 Unicode 为0x4E2D)。
    • UTF-8:变长编码(1-4 字节),英文兼容 ASCII(1 字节),中文 3 字节,传输容错性强(推荐使用)。
  2. Java 编码转换

    • String/char内存中为 Unicode,转字节数组:getBytes("UTF-8")(避免默认编码,推荐用StandardCharsets.UTF_8)。
    • 字节数组转字符串:new String(byte[], charset)(指定编码如GBK/UTF-8,确保一致性)。
五、最佳实践与注意事项
  1. 不可变性设计

    • 构造方法中避免直接引用外部可变数组,需复制(如this.scores = Arrays.copyOf(scores, scores.length)),防止外部修改影响内部状态。
  2. 性能优化

    • 频繁拼接用StringBuilder/StringJoiner,减少临时对象创建;split()replaceAll()谨慎使用正则,避免不必要的转义。
  3. 编码规范

    • 始终明确指定编码(如 UTF-8),确保跨平台兼容性;处理用户输入时,注意编码转换可能导致的乱码问题。
六、核心总结
  • 不可变性:String 操作返回新对象,安全且线程友好,但需注意性能开销。
  • 比较规则 :内容比较用equals(),引用比较用==,常量池优化是特例而非通用规则。
  • 编码转换 :内存中为 Unicode,通过getBytes()和构造函数与字节数组交互,UTF-8 是首选编码。
  • 工具方法 :熟练掌握trim()substring()format()等,结合正则提升灵活性,同时避免常见陷阱(如错误转义)。

一、StringBuilder 核心作用

  1. 高效字符串拼接

    • 解决String不可变导致的性能问题:String拼接时每次生成新对象,循环中大量创建临时对象浪费内存、影响 GC 效率。
    • StringBuilder是可变对象,可预分配缓冲区,通过append()等方法直接修改内部字符数组,避免临时对象创建。
  2. 适用场景:循环内高频字符串拼接(如日志生成、SQL 语句构造等)。

二、核心特性与用法

  1. 链式操作

    • 方法(如append()insert())返回this,支持连续调用,代码更简洁。
    • 示例:

    java

    go 复制代码
    new StringBuilder()
        .append("Hello, ")
        .append("Bob")
        .insert(0, "Mr "); // 结果:Mr Hello, Bob
  2. 源码原理 :通过返回当前实例(return this)实现链式调用,用户可模仿设计自定义链式操作类(如计数器Adder)。

三、与 StringBuffer 的对比

特性 StringBuilder StringBuffer
线程安全 非线程安全(无同步) 线程安全(方法加synchronized
性能 更高(无同步开销) 较低(同步导致性能损耗)
推荐场景 单线程或非并发场景 早期多线程场景(现完全被StringBuilder替代,无需使用)

四、实践与注意事项

  1. 编译器优化 :普通String拼接(非循环中)会被编译器优化为StringConcatFactory操作,无需手动改写为StringBuilder

  2. 练习示例 :构造INSERT语句时,通过循环拼接字段和占位符?,避免硬编码,提高通用性。

    • 正确实现思路:

    java

    scss 复制代码
    static String buildInsertSql(String table, String[] fields) {
        StringBuilder sb = new StringBuilder();
        sb.append("INSERT INTO ").append(table).append(" (");
        for (int i = 0; i < fields.length; i++) {
            sb.append(fields[i]);
            if (i < fields.length - 1) sb.append(", "); // 非最后一个字段添加逗号
        }
        sb.append(") VALUES (");
        for (int i = 0; i < fields.length; i++) {
            sb.append("?");
            if (i < fields.length - 1) sb.append(", "); // 生成占位符
        }
        sb.append(")");
        return sb.toString();
    }

练习

java 复制代码
public class Main {
    public static void main(String[] args) {
        String[] fields = { "name", "position", "salary" };
        String table = "employee";
        String insert = buildInsertSql(table, fields);
        System.out.println(insert);
        String s = "INSERT INTO employee (name, position, salary) VALUES (?, ?, ?)";
        System.out.println(s.equals(insert) ? "测试成功" : "测试失败");
    }

    static String buildInsertSql(String table, String[] fields) {
        StringBuilder sb = new StringBuilder(1024);
        sb.append("INSERT INTO ")
                .append(table);
        sb.append(" (");
        for (int i = 0; i < fields.length; i++) {
            sb.append(fields[i]+ (i < fields.length - 1 ? ", " : ")"));
        }
        sb.append(" VALUES (");
        for (int i = 0; i < fields.length; i++) {
            sb.append("?"+ (i < fields.length - 1 ? ", " : ")"));
        }
        return sb.toString();
    }
}

StringJoiner的教程,主要介绍StringJoiner的用法、与相关方法的对比及练习,具体内容如下:

  • 核心功能:用于高效拼接带分隔符的字符串,可附加固定的开头和结尾字符串,简化字符串拼接逻辑,避免手动处理分隔符和首尾字符。

  • 基本用法

    • 构造函数StringJoiner(分隔符):创建仅包含分隔符的 Joiner,如new StringJoiner(", ")StringJoiner(分隔符, 开头, 结尾):创建包含分隔符、开头和结尾的 Joiner,如new StringJoiner(", ", "Hello ", "!")
    • 核心方法add(String element):向 Joiner 中添加元素,自动用分隔符连接。toString():返回最终拼接的字符串。
  • String.join()对比

    • String.join(分隔符, 数组):静态方法,内部使用StringJoiner,适用于简单的分隔符拼接(无需开头 / 结尾),代码更简洁。
    • StringJoiner:支持自定义开头和结尾,灵活性更高,适合复杂拼接场景(如 SQL 语句构造)。
  • 示例代码

    • 基础拼接 :通过StringJoiner循环添加元素,自动处理分隔符。
    • 带首尾字符串:在构造函数中指定开头(如 "SELECT")和结尾(如 "FROM table"),直接生成完整语句。

包装类型

转换为包装类型的目的是说,可以调用包装类型的静态方法。

Java 包装类型详解

一、基本概念
  1. 数据类型分类

    • 基本类型 (8 种):byteshortintlongbooleanfloatdoublechar不能赋值为null
    • 引用类型 :所有classinterface,可赋值为null
  2. 包装类型定义

    • 为基本类型提供对应的引用类型(java.lang包下),如Integer对应intBoolean对应boolean等,便于将基本类型视为对象操作。
二、自动装箱与拆箱(JDK 1.5+)
  1. 核心机制

    • 自动装箱 :编译期自动将基本类型转为包装类型(如Integer n = 100;等价于Integer.valueOf(100))。
    • 自动拆箱 :编译期自动将包装类型转为基本类型(如int x = n;等价于n.intValue())。
  2. 注意事项

    • 效率影响 :装箱拆箱发生在编译期,但运行时仍需执行对应方法(如valueOf()intValue()),频繁操作会影响性能。
    • 空指针风险 :拆箱时若包装类型为null,会抛出NullPointerException(如Integer n = null; int x = n;)。
三、不变类特性
  1. 不可变性

    • 所有包装类型均为不变类 (如Integervalue字段为final),实例创建后值不可修改。
  2. 对象比较

    • 禁止使用== :包装类型是引用类型,==比较引用地址而非值。
    • 必须使用equals() :即使值相同,不同实例的==可能为true(如小整数缓存优化),但需统一用equals()保证语义正确。
    • 缓存优化Integer.valueOf()-128~127的整数返回缓存实例,超出范围则创建新实例,但代码逻辑不应依赖此优化。
四、常用方法与功能
  1. 创建实例

    • 推荐静态工厂方法Integer.valueOf(int)Integer.valueOf(String),而非new Integer()(后者在 Java 9 + 被弃用,且无法利用缓存)。
  2. 进制转换

    • 解析字符串Integer.parseInt("100")(十进制)、Integer.parseInt("100", 16)(十六进制)。
    • 格式化为字符串Integer.toString(n, 36)(36 进制)、toHexString(十六进制)、toBinaryString(二进制)等。
  3. 静态变量与工具方法

    • 极值:Integer.MAX_VALUEInteger.MIN_VALUE
    • 类型信息:Long.SIZE(位数)、Long.BYTES(字节数)。
    • 无符号转换:Byte.toUnsignedInt(-1)byte-1转为无符号255(适用于byte/short/int转更高位无符号类型)。
  4. 继承体系

    • 整数和浮点数包装类型继承自Number,可转换为多种基本类型(如Number num = new Integer(999); int n = num.intValue();)。
五、最佳实践
  1. 对象创建 :优先使用静态工厂方法(如valueOf()),而非new操作符,以便库实现优化(如缓存)。
  2. 对象比较 :始终用equals()比较包装类型值,避免依赖==的缓存优化特性。
  3. 数据处理:利用包装类提供的工具方法(进制转换、无符号运算等),分离数据存储与显示逻辑。

javaBean

可以理解为只是一种协议规定。

一、JavaBean 定义与规范
  1. 基本定义

    • 符合特定命名规范的 Java 类,通常包含:

      • private 修饰的实例字段
      • public 修饰的字段读写方法(Getter/Setter)
    • 示例:

      typescript 复制代码
      public class Person {
          private String name;
          private int age;
          // Getter 和 Setter 方法
          public String getName() { return name; }
          public void setName(String name) { this.name = name; }
      }
  2. 命名规范

    • 普通字段

      • 读方法(Getter):getXyz()(首字母大写,前缀 get
      • 写方法(Setter):setXyz(Type value)(前缀 set
    • 布尔字段

      • 读方法通常为 isXyz()(如 isChild()
    • 属性类型

      • 读写属性:同时有 Getter 和 Setter
      • 只读属性 :仅有 Getter(如 getAge()
      • 只写属性:仅有 Setter(不常见)
    • 特殊说明 :属性可通过方法逻辑计算(不一定对应实际字段),例如 isChild() 可根据 age 计算返回值。

二、JavaBean 的作用
  1. 核心用途

    • 数据封装与传输:将相关数据组合为一个对象,便于在组件间传递(如 Web 开发中的参数传递)。
    • IDE 工具支持:通过 IDE(如 Eclipse、IntelliJ IDEA)自动生成 Getter/Setter,提升开发效率。
  2. 工具使用示例

    • 在 Eclipse 中,右键点击类文件,通过 Source -> Generate Getters and Setters 快速生成方法。
三、枚举 JavaBean 属性(反射 API)

通过 Java 核心库的 Introspector 类可动态获取 JavaBean 的属性信息:

  1. 关键类与方法

    • BeanInfo info = Introspector.getBeanInfo(Class<?> clazz):获取类的元信息。
    • PropertyDescriptor:封装属性名称、Getter 和 Setter 方法。
  2. 示例代码

    java 复制代码
    import java.beans.*;
    public class Main {
        public static void main(String[] args) throws Exception {
            BeanInfo info = Introspector.getBeanInfo(Person.class);
            for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
                System.out.println("属性名: " + pd.getName());
                System.out.println("读方法: " + pd.getReadMethod());
                System.out.println("写方法: " + pd.getWriteMethod());
            }
        }
    }
  3. 注意事项

    • 会包含从 Object 继承的 getClass() 方法对应的 class 属性,需按需过滤。
四、核心要点总结
  1. 本质 :通过 Getter/Setter 命名规范定义属性的 Java 类,非 Java 语法强制,而是编程约定。

  2. 核心优势

    • 数据封装性强,符合面向对象设计原则。
    • 兼容反射机制,便于框架(如 Spring)或工具动态操作属性。
  3. 最佳实践

    • 使用 IDE 自动生成 Getter/Setter,避免手动编写冗余代码。
    • 通过 Introspector 实现框架级属性解析(如序列化、配置绑定)。

BigInteger

一、概述
  • 用途 :处理超过 Java 原生long类型(64 位)范围的大整数运算,支持任意精度的整数。
  • 实现 :通过java.math.BigInteger类实现,内部使用int[]数组模拟大整数。
二、核心特性
  1. 不可变类 :与IntegerLong类似,实例一旦创建不可修改。
  2. 继承自Number :支持转换为基本数值类型(如byteshortintlongfloatdouble)。
  3. 无范围限制 :突破long类型的数值范围限制,但运算速度较原生类型慢(因需软件模拟)。
三、基本用法与运算
  1. 创建实例

    ini 复制代码
    BigInteger bi = new BigInteger("1234567890"); // 直接通过字符串初始化
  2. 算术运算

    • 加法:add(BigInteger val)

    • 乘法:multiply(BigInteger val)

    • 幂运算:pow(int exponent)

    • 示例:

      csharp 复制代码
      BigInteger sum = i1.add(i2); // 加法运算
      System.out.println(bi.pow(5)); // 计算5次幂
  3. 与原生类型对比

    • long运算速度快但范围有限(±9e18),BigInteger范围无限但速度慢。
四、类型转换
  1. 普通转换方法(可能丢失精度或溢出):

    • byteValue()shortValue()intValue()longValue()floatValue()doubleValue()
    • 例:longValue()BigInteger转为long,超出范围时截断高位。
  2. 精确转换方法(超出范围时抛异常):

    • intValueExact()longValueExact()等,若结果超出目标类型范围,抛出ArithmeticException
  3. 特殊场景

    • BigInteger值超过float最大范围(3.4×10³⁸)时,floatValue()返回Infinity

BigDecimal

一、BigDecimal 核心特性

  1. 精确表示小数

    • 用于任意精度的浮点运算,避免float/double的精度丢失问题,常见于财务计算。
    • 内部通过BigInteger(整数部分)和scale(小数位数)表示。
  2. 不可变对象 :所有运算(如加减乘除)均返回新的BigDecimal实例,原对象不变。

二、创建与初始化

  • 推荐使用字符串构造器

    java 复制代码
    BigDecimal bd = new BigDecimal("123.4567"); // 精确初始化,避免浮点精度误差

    ❗ 避免使用new BigDecimal(double),因double本身存在二进制精度丢失(如new BigDecimal(0.1)实际存储值为0.10000000149)。

三、小数位数与格式处理

  1. 获取小数位数(scale)

    • scale()方法返回小数位数:
    java 复制代码
    new BigDecimal("123.45").scale(); // 2  
    new BigDecimal("1234500").scale(); // 0(整数无小数位)  
  2. 去除末尾零(stripTrailingZeros)

    • 移除小数末尾的零,可能改变scale,若结果为整数且末尾有零,scale为负数(如1234500.stripTrailingZeros().scale() = -2,表示末尾有 2 个零)。

四、算术运算

  1. 基础运算(加、减、乘)

    • 直接调用对应方法,精度不丢失:
    java 复制代码
    BigDecimal result = d1.add(d2); // 加法  
    result = d1.multiply(d2); // 乘法  
  2. 除法(divide)

    • 必须指定精度和舍入模式 ,否则除不尽时抛出ArithmeticException
    java 复制代码
    // 保留10位小数,四舍五入  
    BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP);  
    • 常用舍入模式:RoundingMode.HALF_UP(四舍五入)、RoundingMode.DOWN(直接截断)。
  3. 除法与余数(divideAndRemainder)

    • 返回数组[商, 余数],商为整数(小数部分为 0),余数绝对值小于除数:
    ini 复制代码
    BigDecimal[] dr = n.divideAndRemainder(m);  
    if (dr[1].signum() == 0) { // 余数为0,n是m的整数倍  
    }  

五、精度调整(setScale)

  • 设置指定小数位数,支持舍入或截断:
java 复制代码
BigDecimal d1 = new BigDecimal("123.456789");  
d1.setScale(4, RoundingMode.HALF_UP); // 123.4568(四舍五入)  
d1.setScale(4, RoundingMode.DOWN); // 123.4567(直接截断)  

六、比较操作

  • 值比较(忽略 scale 差异) :使用compareTo(),返回 - 1(小于)、0(等于)、1(大于):
java 复制代码
BigDecimal d1 = new BigDecimal("123.456");  
BigDecimal d2 = new BigDecimal("123.45600");  
d1.compareTo(d2); // 0(值相等,忽略末尾零)  
  • 严格相等(值和 scale 均相同) :使用equals(),但实际开发中很少用,因业务场景更关注值是否相等:
java 复制代码
d1.equals(d2); // false(scale不同,d1.scale=3,d2.scale=5)  

Java 常用工具类

一、核心工具类概述

Java 核心库提供了多个常用工具类,用于数学计算、进制转换、随机数生成等场景,显著提升开发效率。以下是重点介绍的工具类:

二、工具类详解
1. Math 类
  • 功能:提供数学运算的静态方法和常量。

  • 常用方法

    • 基础运算abs()(绝对值)、max()/min()(最值)、pow(x, y)(x 的 y 次方)、sqrt()(平方根)。
    • 指数与对数exp(x)(e 的 x 次方)、log()(自然对数)、log10()(以 10 为底的对数)。
    • 三角函数sin()cos()tan()等。
    • 随机数random()生成[0, 1)的随机数,可通过公式扩展到指定区间。
  • 常量Math.PI(圆周率)、Math.E(自然对数底数)。

  • 注意 :与StrictMath的区别在于Math针对平台优化性能,而StrictMath保证跨平台计算结果一致。

2. HexFormat 类(Java 17+)
  • 功能 :简化byte[]数组与十六进制字符串的转换,支持格式定制。

  • 常用方法

    • 编码formatHex(byte[] data)将字节数组转为十六进制字符串,可通过ofDelimiter()withPrefix()withUpperCase()定制格式(如添加分隔符、前缀、大写字母)。
    • 解码parseHex(String hex)将十六进制字符串转为字节数组。
  • 示例
    HexFormat.of().formatHex("Hello".getBytes())48656c6c6f

3. Random 类
  • 功能:生成伪随机数,序列由初始种子决定。

  • 特点

    • 若不指定种子,默认使用系统时间戳,每次运行结果不同。
    • 指定种子(如new Random(12345))时,生成固定序列的伪随机数。
  • 常用方法

    • nextInt()/nextLong()/nextFloat()/nextDouble(),支持指定范围(如nextInt(10)生成[0, 10)的整数)。
  • 注意Math.random()内部调用Random,但无法指定种子。

4. SecureRandom 类
  • 功能:生成安全的随机数,用于密码学等对随机性要求高的场景。

  • 特点

    • 种子由系统提供的安全熵(如 CPU 热噪声、磁盘 I/O 事件)生成,不可预测。
    • 提供高强度实现(getInstanceStrong())和普通实现(new SecureRandom()),前者可能因熵不足阻塞线程。
  • 常用方法

    • nextInt()生成安全随机整数,nextBytes(byte[] buffer)填充安全随机字节。
  • 注意必须用于安全场景 ,绝不能用Random替代(后者种子可预测,存在安全风险)。

三、核心区别对比
工具类 随机性类型 种子来源 应用场景
Math 伪随机数(通过 Random) 系统时间戳(默认) 普通数学计算、非安全随机
Random 伪随机数 自定义或系统时间 非安全场景(如游戏随机)
SecureRandom 安全随机数(基于熵) 系统安全熵 密码学、加密密钥生成
相关推荐
猴哥源码2 分钟前
基于Java+SpringBoot的农事管理系统
java·spring boot
面朝大海,春不暖,花不开17 分钟前
Java网络编程:TCP/UDP套接字通信详解
java·网络·tcp/ip
慕y2741 小时前
Java学习第十五部分——MyBatis
java·学习·mybatis
大鸡腿同学1 小时前
身弱武修法:玄之又玄,奇妙之门
后端
A__tao1 小时前
SQL 转 Java 实体类工具
java·数据库·sql
喝可乐的布偶猫1 小时前
Java类变量(静态变量)
java·开发语言·jvm
TDengine (老段)1 小时前
TDengine STMT2 API 使用指南
java·大数据·物联网·时序数据库·iot·tdengine·涛思数据
喝可乐的布偶猫2 小时前
韩顺平之第九章综合练习-----------房屋出租管理系统
java·开发语言·ide·eclipse
Code季风2 小时前
深入理解微服务中的服务注册与发现(Consul)
java·运维·微服务·zookeeper·架构·go·consul
光军oi2 小时前
java微服务(Springboot篇)——————IDEA搭建第一个Springboot入门项目
java·spring boot·微服务