JDK 常用工具类系统分类与实战示例

Java中String类在JDK 8与JDK 11,JDK 17的底层实现变迁 JDK 8中,`String`对象基于`char[]`数组存储,每个字符占2个字节,支持完整的Unicode编码。到了JDK 11,为了优化内存使用,对于仅包含ASCII或类似单字节编码字符的字符串,`String`类改用`byte[]`数组存储,并引入了`coder`属性标识编码类型,节省了内存。而在JDK 17中,进一步引入了`hashIsZero`字段来优化哈希码的计算与存储,使得哈希码可以在创建时立即计算并标记是否为零,从而提升性能。 阅读详情

作为一名 Java 后端开发程序员,熟练掌握 JDK 自带的工具类,是提升代码质量、效率与健壮性的关键。这些工具类经过严格测试、性能优化、线程安全设计,远胜于“手写轮子”。

下面我将 JDK 常用工具类按功能分类,精选高频、高价值的类,结合真实业务场景给出完整、可运行、带详细中文注释的示例,助你彻底掌握其在生产环境中的最佳实践。


✅ JDK 常用工具类系统分类与实战示例


一、集合操作工具类(java.util 包)

1. Collections —— 集合的静态工具方法(排序、查找、不可变封装)

作用:提供对 List、Set、Map 的通用操作,避免手动循环。

import java.util.*;

public class CollectionsExample {

    public static void main(String[] args) {
        List<String> names = Arrays.asList("张三", "李四", "王五", "赵六");

        // ✅ sort:对列表排序(自然顺序)
        Collections.sort(names);
        System.out.println("排序后:" + names); // [张三, 李四, 王五, 赵六]

        // ✅ reverse:反转列表
        Collections.reverse(names);
        System.out.println("反转后:" + names); // [赵六, 王五, 李四, 张三]

        // ✅ shuffle:随机打乱(用于抽奖、推荐排序)
        Collections.shuffle(names, new Random(100)); // 固定种子,便于测试
        System.out.println("随机打乱:" + names);

        // ✅ binarySearch:二分查找(要求已排序!)
        Collections.sort(names); // 必须先排序
        int index = Collections.binarySearch(names, "王五");
        System.out.println("王五索引:" + index); // 输出:2

        // ✅ max/min:查找最大/最小元素(需可比较)
        String maxName = Collections.max(names);
        String minName = Collections.min(names);
        System.out.println("最大:" + maxName + ",最小:" + minName);

        // ✅ unmodifiableXXX:创建不可变集合(防止外部修改,线程安全)
        List<String> immutableList = Collections.unmodifiableList(new ArrayList<>(names));
        // immutableList.add("新用户"); // ❌ 运行时报:UnsupportedOperationException

        // ✅ singleton:创建仅含一个元素的集合(常用于返回默认值)
        Set<String> singleUser = Collections.singleton("admin");
        System.out.println("单用户集合:" + singleUser); // [admin]

        // ✅ emptyXXX:返回空集合(避免返回 null)
        List<String> empty = Collections.emptyList();
        if (empty.isEmpty()) {
            System.out.println("✅ 返回空集合而非 null,安全可靠");
        }
    }
}

📌 应用场景:

  • API 返回不可变集合(防篡改)
  • 单元测试中构造测试数据
  • 避免 null 返回,使用 emptyList()、emptySet() 提升健壮性

2. Arrays —— 数组操作工具(排序、查找、转换)

作用:对数组进行高效操作,支持 toString()、equals()、copyOf()。

import java.util.Arrays;

public class ArraysExample {

    public static void main(String[] args) {
        int[] scores = {85, 92, 76, 98, 63};

        // ✅ sort:排序数组(原地修改)
        Arrays.sort(scores);
        System.out.println("排序后分数:" + Arrays.toString(scores)); // [63, 76, 85, 92, 98]

        // ✅ binarySearch:二分查找(必须排序!)
        int index = Arrays.binarySearch(scores, 92);
        System.out.println("92 的索引:" + index); // 输出:3

        // ✅ equals:比较两个数组内容是否相等(不是引用!)
        int[] scores2 = {63, 76, 85, 92, 98};
        boolean isEqual = Arrays.equals(scores, scores2);
        System.out.println("数组内容相等:" + isEqual); // true

        // ✅ toString:将数组转为可读字符串(替代手动拼接)
        System.out.println("数组内容:" + Arrays.toString(scores)); // [63, 76, 85, 92, 98]

        // ✅ fill:填充数组(如初始化默认值)
        int[] status = new int[5];
        Arrays.fill(status, 0); // 全部设为 0(未处理)
        System.out.println("初始化状态:" + Arrays.toString(status)); // [0, 0, 0, 0, 0]

        // ✅ copyOf:复制数组(扩展或截断)
        int[] extended = Arrays.copyOf(scores, 8); // 扩展到8个元素,后3个为0
        System.out.println("扩展后:" + Arrays.toString(extended)); // [63, 76, 85, 92, 98, 0, 0, 0]

        // ✅ asList:数组转 List(注意:返回的是固定大小的 List)
        List<Integer> list = Arrays.asList(1, 2, 3); // ⚠️ 不可 add/remove
        // list.add(4); // ❌ 抛出 UnsupportedOperationException
        // ✅ 正确做法:包装成可变集合
        List<Integer> mutableList = new ArrayList<>(Arrays.asList(1, 2, 3));
        mutableList.add(4);
        System.out.println("可变列表:" + mutableList); // [1, 2, 3, 4]
    }
}

📌 应用场景:

  • 从数据库查询结果转为数组后排序
  • 配置项初始化(如白名单数组)
  • 避免 null 数组,使用 Arrays.asList() 快速构造测试数据

二、日期与时间工具类(java.time 包 —— JDK 8+ 推荐)

替代过时的 Date、SimpleDateFormat,线程安全、API 清晰。

1. LocalDateTime / LocalDate / LocalTime
import java.time.*;
import java.time.format.DateTimeFormatter;

public class DateTimeExample {

    public static void main(String[] args) {
        // ✅ LocalDateTime:日期+时间(无时区)
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间:" + now); // 2025-10-12T10:30:45.123

        // ✅ LocalDate:仅日期(如生日、合同日期)
        LocalDate birthDate = LocalDate.of(1990, 5, 15);
        System.out.println("出生日期:" + birthDate);

        // ✅ LocalTime:仅时间(如营业时间)
        LocalTime openTime = LocalTime.of(9, 0); // 09:00
        System.out.println("开门时间:" + openTime);

        // ✅ plus / minus:日期时间加减
        LocalDateTime oneWeekLater = now.plusWeeks(1);
        System.out.println("一周后:" + oneWeekLater);

        // ✅ between:计算时间差(天数)
        long daysBetween = ChronoUnit.DAYS.between(birthDate, LocalDate.now());
        System.out.println("年龄(天):" + daysBetween);

        // ✅ format:格式化输出(线程安全!)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatted = now.format(formatter);
        System.out.println("格式化时间:" + formatted); // 2025-10-12 10:30:45

        // ✅ parse:字符串转日期时间
        LocalDateTime parsed = LocalDateTime.parse("2025-10-12T10:30:45", formatter);
        System.out.println("解析结果:" + parsed);
    }
}
2. Duration / Period —— 时间间隔计算
import java.time.Duration;
import java.time.Period;
import java.time.LocalDateTime;

public class DurationPeriodExample {

    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.now();
        try {
            Thread.sleep(2000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        LocalDateTime end = LocalDateTime.now();

        // ✅ Duration:计算两个时间点的差值(秒、毫秒)
        Duration duration = Duration.between(start, end);
        System.out.println("操作耗时:" + duration.toMillis() + " 毫秒");
        System.out.println("操作耗时:" + duration.getSeconds() + " 秒");

        // ✅ Period:计算两个日期的差值(年、月、日)
        LocalDate startDate = LocalDate.of(2024, 1, 15);
        LocalDate endDate = LocalDate.of(2025, 3, 20);
        Period period = Period.between(startDate, endDate);
        System.out.println("项目周期:" + period.getYears() + "年 " + period.getMonths() + "月 " + period.getDays() + "天");
        // 输出:1年 2月 5天
    }
}

📌 应用场景:

  • 记录接口响应耗时(监控系统)
  • 计算用户年龄、会员有效期
  • 日志时间戳格式化(避免 SimpleDateFormat 线程不安全问题)
  • ✅ 强烈推荐:所有新项目使用 java.time,禁用 Date 和 SimpleDateFormat

三、字符串处理工具类(java.util & java.lang.String)

1. StringJoiner —— 高效拼接带分隔符的字符串

替代 StringBuilder + 手动拼接逗号,语法更清晰。

import java.util.StringJoiner;

public class StringJoinerExample {

    public static void main(String[] args) {
        // ✅ 创建 StringJoiner,指定分隔符、前缀、后缀
        StringJoiner joiner = new StringJoiner(", ", "[", "]");

        // ✅ 添加多个元素
        joiner.add("苹果");
        joiner.add("香蕉");
        joiner.add("橙子");
        joiner.add("葡萄");

        String result = joiner.toString();
        System.out.println("水果列表:" + result); // [苹果, 香蕉, 橙子, 葡萄]

        // ✅ 与 Stream 结合使用(推荐)
        List<String> fruits = Arrays.asList("苹果", "香蕉", "橙子");
        String joined = fruits.stream()
                              .collect(Collectors.joining(", ", "[", "]"));
        System.out.println("Stream拼接:" + joined); // [苹果, 香蕉, 橙子]

        // ✅ 实际应用:构建 SQL IN 子句
        List<Long> userIds = Arrays.asList(101L, 102L, 103L);
        String inClause = "WHERE user_id IN (" + String.join(",", userIds.stream().map(String::valueOf).toArray(String[]::new)) + ")";
        System.out.println("SQL 条件:" + inClause); // WHERE user_id IN (101,102,103)
    }
}
2. String.format() —— 格式化输出(替代拼接)
public class StringFormatExample {

    public static void main(String[] args) {
        String name = "张三";
        int age = 28;
        double salary = 15000.50;

        // ✅ 格式化输出(类似 printf),清晰、可读、支持国际化
        String message = String.format("员工 %s,%d 岁,月薪 %.2f 元", name, age, salary);
        System.out.println(message); // 员工 张三,28 岁,月薪 15000.50 元

        // ✅ 多行日志格式化
        String log = String.format(
            "【%s】用户 %s(ID: %d)于 %s 登录系统,IP: %s",
            java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss")),
            name,
            1001,
            "2025-10-12",
            "192.168.1.100"
        );
        System.out.println(log);
    }
}

📌 应用场景:

  • 日志记录、API 响应格式化
  • 邮件模板、短信内容生成
  • 避免 + 拼接导致的性能问题和可读性差

3、正则表达式工具:java.util.regex.Pattern 和 Matcher

作用:高性能字符串匹配、提取、替换(比 String.contains()、split() 更强大)。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexExample {

    public static void main(String[] args) {
        String text = "联系邮箱:zhangsan@example.com,电话:138-0013-8000,网址:https://www.example.com";

        // ✅ 提取邮箱:使用 Pattern 编译正则(复用,性能高)
        Pattern emailPattern = Pattern.compile("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b");
        Matcher emailMatcher = emailPattern.matcher(text);

        System.out.println("🔍 提取邮箱:");
        while (emailMatcher.find()) {
            System.out.println("→ " + emailMatcher.group()); // 输出:zhangsan@example.com
        }

        // ✅ 提取手机号(支持多种格式)
        Pattern phonePattern = Pattern.compile("\\d{3}-\\d{4}-\\d{4}|\\d{11}");
        Matcher phoneMatcher = phonePattern.matcher(text);

        System.out.println("📞 提取手机号:");
        while (phoneMatcher.find()) {
            System.out.println("→ " + phoneMatcher.group()); // 输出:138-0013-8000
        }

        // ✅ 替换敏感信息(脱敏)
        String masked = text.replaceAll("\\d{3}-\\d{4}-\\d{4}", "***-****-****");
        System.out.println("脱敏后:" + masked);
        // 输出:联系邮箱:zhangsan@example.com,电话:***-****-****,网址:https://www.example.com

        // ✅ 验证邮箱格式(登录表单校验)
        String email = "test@domain.com";
        boolean isValid = Pattern.matches("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b", email);
        System.out.println("邮箱是否有效:" + isValid); // true

        // ✅ 实际应用场景:日志解析、表单校验、敏感词过滤、数据清洗
    }
}

📌 使用场景:

  • 用户输入校验(邮箱、手机号、身份证)
  • 日志中提取 IP、URL、错误码
  • 敏感信息脱敏(银行卡号、身份证号)
  • ✅ 最佳实践:将 Pattern 编译为静态常量,避免每次创建(线程安全、高效)
private static final Pattern EMAIL_PATTERN = Pattern.compile(
    "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b"
);

4、基础编码工具:java.util.Base64

作用:将二进制数据编码为 ASCII 字符串(用于传输、存储),替代过时的 sun.misc.BASE64Encoder。

import java.util.Base64;

public class Base64Example {

    public static void main(String[] args) throws Exception {
        String original = "Hello, Java Base64! 你好,世界!";

        // ✅ 编码:字符串 → Base64
        String encoded = Base64.getEncoder().encodeToString(original.getBytes("UTF-8"));
        System.out.println("Base64 编码:" + encoded);
        // 输出:SGVsbG8sIEphdmEgQmFzZTY0ISA556uL5L2g5L2c5L2T!

        // ✅ 解码:Base64 → 原始字符串
        byte[] decodedBytes = Base64.getDecoder().decode(encoded);
        String decoded = new String(decodedBytes, "UTF-8");
        System.out.println("Base64 解码:" + decoded); // Hello, Java Base64! 你好,世界!

        // ✅ 实际应用场景:
        // 1. HTTP Basic Auth:用户名密码编码
        String credentials = "admin:password123";
        String authHeader = "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes("UTF-8"));
        System.out.println("Authorization 头:" + authHeader);
        // 输出:Basic YWRtaW46cGFzc3dvcmQxMjM=

        // 2. 图片/文件转 Base64 嵌入 HTML 或 JSON
        // 3. JWT Token 的 payload 编码

        // ✅ ✅ ✅ 推荐:所有新项目使用 `java.util.Base64`,禁用 sun.misc 包(非标准,可能被移除)
    }
}

📌 使用场景:

  • HTTP 请求头认证(Basic Auth)
  • 图片、PDF 等二进制数据嵌入 JSON 响应
  • JWT、Token 传输
  • ✅ JDK 8+ 标准化,性能高、线程安全

五、数学与随机工具类

1. Math —— 数学运算(幂、对数、取整、绝对值)
public class MathExample {

    public static void main(String[] args) {
        // ✅ abs:绝对值
        System.out.println("绝对值:" + Math.abs(-10.5)); // 10.5

        // ✅ max / min:取最大/最小值
        System.out.println("最大值:" + Math.max(10, 20)); // 20

        // ✅ pow:幂运算
        System.out.println("2^8:" + Math.pow(2, 8)); // 256.0

        // ✅ sqrt:平方根
        System.out.println("√144:" + Math.sqrt(144)); // 12.0

        // ✅ ceil / floor:向上/向下取整
        System.out.println("ceil(3.2):" + Math.ceil(3.2)); // 4.0
        System.out.println("floor(3.8):" + Math.floor(3.8)); // 3.0

        // ✅ round:四舍五入
        System.out.println("round(3.5):" + Math.round(3.5)); // 4

        // ✅ random:生成 0.0 ~ 1.0 的随机数
        double random = Math.random();
        System.out.println("随机数:" + random);

        // ✅ 生成 1~100 的随机整数
        int randomInt = (int) (Math.random() * 100) + 1;
        System.out.println("1~100 随机数:" + randomInt);
    }
}
2. Random / SecureRandom —— 随机数生成
import java.security.SecureRandom;
import java.util.Random;

public class RandomExample {

    public static void main(String[] args) {
        Random random = new Random();

        // ✅ 生成随机整数(0 ~ 99)
        int randInt = random.nextInt(100);
        System.out.println("随机整数:" + randInt);

        // ✅ 生成随机布尔值
        boolean flag = random.nextBoolean();
        System.out.println("随机布尔:" + flag);

        // ✅ SecureRandom:加密安全随机数(用于 token、密钥、验证码)
        SecureRandom secureRandom = new SecureRandom();
        byte[] token = new byte[16];
        secureRandom.nextBytes(token);
        String securityToken = java.util.Base64.getEncoder().encodeToString(token);
        System.out.println("安全 Token:" + securityToken); // 如:aB3xK9pLmN2qR8vYtZ5w==
    }
}

四、安全的随机数生成器:java.security.SecureRandom(再次强调!)

作用:密码学安全的随机数生成器,防预测、防攻击,用于令牌、密钥、验证码。

import java.security.SecureRandom;

public class SecureRandomExample {

    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();

        // ✅ 生成 16 字节随机字节(用于 AES 密钥、JWT 签名密钥)
        byte[] key = new byte[16];
        secureRandom.nextBytes(key);
        String secretKey = java.util.Base64.getEncoder().encodeToString(key);
        System.out.println("🔐 生成的安全密钥:" + secretKey);

        // ✅ 生成 6 位数字验证码(短信/邮箱验证)
        int verificationCode = secureRandom.nextInt(900000) + 100000; // 100000 ~ 999999
        System.out.println("📱 验证码:" + verificationCode);

        // ✅ 生成 UUID(安全版本)
        String uuid = java.util.UUID.randomUUID().toString();
        System.out.println("🔗 安全 UUID:" + uuid);

        // ✅ 生成 32 位随机字符串(用于临时登录令牌)
        StringBuilder token = new StringBuilder();
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        for (int i = 0; i < 32; i++) {
            token.append(chars.charAt(secureRandom.nextInt(chars.length())));
        }
        System.out.println("🔑 临时登录令牌:" + token.toString());

        // ✅ 实际应用场景:
        // - JWT 签名密钥
        // - API Key / Client Secret
        // - 重置密码 Token
        // - 会话 ID(Session ID)
        // ✅ ❗ **生产环境必须使用 SecureRandom!禁止使用 Random!**
    }
}

📌 安全规范:

  • 任何用于身份认证、加密、防重放攻击的随机值,必须使用 SecureRandom
  • java.util.Random 是伪随机,可被预测,在金融、支付、登录系统中是严重安全漏洞

📌 应用场景:

  • 生成订单号、验证码、临时密码
  • 模拟测试数据
  • ✅ 生产环境生成安全令牌,必须使用 SecureRandom,避免 Random 被预测

二、安全的系统属性与环境变量访问:java.lang.System.getProperty() / getenv()

作用:读取 JVM 启动参数和操作系统环境变量,但必须做空值检查和类型转换。

public class SystemPropertiesExample {

    public static void main(String[] args) {
        // ✅ 获取 JVM 系统属性(启动参数)
        String javaVersion = System.getProperty("java.version");
        String javaHome = System.getProperty("java.home");
        String osName = System.getProperty("os.name");
        String userDir = System.getProperty("user.dir"); // 当前工作目录

        System.out.println("Java 版本:" + javaVersion);
        System.out.println("Java 安装路径:" + javaHome);
        System.out.println("操作系统:" + osName);
        System.out.println("工作目录:" + userDir);

        // ✅ 获取环境变量(生产环境配置)
        String dbUrl = System.getenv("DB_URL");
        String dbUser = System.getenv("DB_USERNAME");
        String dbPassword = System.getenv("DB_PASSWORD");

        // ✅ 安全处理:永远不要直接使用,必须判空
        if (dbUrl == null || dbUrl.isBlank()) {
            throw new IllegalStateException("❌ 环境变量 DB_URL 未设置,请检查部署配置");
        }
        if (dbPassword == null) {
            System.err.println("⚠️ DB_PASSWORD 未设置,使用默认值(仅限测试)");
            dbPassword = "test123";
        }

        System.out.println("数据库连接:" + dbUrl + " 用户:" + dbUser);

        // ✅ 实际应用:Spring Boot 的 application.yml 中的 ${DB_URL} 就是基于此机制
        // ✅ 生产环境规范:所有敏感配置(密码、密钥)必须通过环境变量注入,禁止写入代码或配置文件!

        // ✅ 获取自定义 JVM 参数(启动时加:-Dapp.mode=prod)
        String appMode = System.getProperty("app.mode", "dev"); // ✅ 提供默认值
        System.out.println("应用模式:" + appMode);

        // ✅ 避免使用 System.setProperty() 修改系统属性(线程不安全,影响全局)
    }
}

📌 使用场景:

  • 读取数据库 URL、API 密钥、端口号(必须用环境变量)
  • 判断运行环境(dev/test/prod)
  • ✅ 安全规范:绝不在代码中硬编码密码、密钥、证书路径,全部通过 -D 或 export 注入

六、文件与 I/O 工具类(java.nio.file —— JDK 7+)

Files —— 文件操作(读写、复制、删除、遍历)
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

public class FilesExample {

    public static void main(String[] args) throws IOException {
        Path source = Paths.get("src/main/resources/input.txt");
        Path target = Paths.get("src/main/resources/output.txt");

        // ✅ write:写入文件(自动创建目录)
        String content = "Hello, Java NIO!\n这是第一行。\n这是第二行。";
        Files.write(target, content.getBytes("UTF-8")); // ✅ 自动创建文件

        // ✅ readAllLines:读取所有行
        List<String> lines = Files.readAllLines(target);
        System.out.println("读取行数:" + lines.size());
        for (String line : lines) {
            System.out.println("→ " + line);
        }

        // ✅ copy:复制文件
        Files.copy(target, Paths.get("src/main/resources/copy.txt"), StandardCopyOption.REPLACE_EXISTING);

        // ✅ exists / isFile / isDirectory:判断文件属性
        System.out.println("文件是否存在:" + Files.exists(target));
        System.out.println("是否为文件:" + Files.isRegularFile(target));

        // ✅ delete:删除文件
        Files.deleteIfExists(Paths.get("src/main/resources/copy.txt")); // 安全删除,不存在不报错

        // ✅ walkFileTree:递归遍历目录(如清理临时文件)
        Path dir = Paths.get("src/main/resources");
        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if (file.toString().endsWith(".tmp")) {
                    System.out.println("删除临时文件:" + file);
                    Files.delete(file);
                }
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

📌 应用场景:

  • 日志文件清理
  • 配置文件读取
  • 批量导入导出文件
  • ✅ 推荐:所有文件操作使用 java.nio.file.Files,替代过时的 java.io.File

我们继续深入挖掘 JDK 中那些真正支撑企业级系统稳定运行的底层工具类。你提到的 Files、Paths 和 Objects 正是其中的“黄金三剑客”——它们在文件操作、路径安全、对象健壮性这三个最易出错的领域,提供了工业级的解决方案。

下面我将为你系统性、深度展开这两个主题:

  • ✅ java.nio.file.Files 与 java.nio.file.Paths:现代文件 I/O 的终极规范
  • ✅ java.util.Objects:对象安全操作的完整实战手册(含 10 种生产场景)

每个示例都基于真实后端开发场景,附带详细中文注释、异常处理、最佳实践和避坑指南,确保你写出的代码不仅正确,而且安全、可维护、经得起生产压测。


✅ 一、现代文件与路径操作:Files 与 Paths(JDK 7+)

为什么必须用 Files 和 Paths?
java.io.File 是 1996 年的设计,不支持 Unicode 路径、无异常细粒度控制、无法处理符号链接、线程不安全。
java.nio.file 是 2011 年重新设计的现代、安全、功能完整的文件系统 API,所有新项目必须使用它。

🌟 实战示例:文件系统操作的完整生产级实践

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Stream;

public class FilesPathsExample {

    // ✅ 路径常量:避免硬编码,提升可移植性
    private static final Path LOG_DIR = Paths.get("logs");
    private static final Path TEMP_DIR = Paths.get("temp");
    private static final Path CONFIG_FILE = Paths.get("config/app.properties");
    private static final DateTimeFormatter FILENAME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");

    public static void main(String[] args) throws IOException {
        // ==================== 1. 路径构建:Paths.get() 是唯一推荐方式 ====================
        // ✅ 正确:使用 Paths.get() 构建路径(自动处理分隔符,跨平台)
        Path logFile = LOG_DIR.resolve("app_" + LocalDateTime.now().format(FILENAME_FORMAT) + ".log");
        System.out.println("日志文件路径:" + logFile); // logs/app_20251012_113045.log

        // ❌ 错误:不要用 String 拼接!Windows 用 \,Linux 用 /,极易出错
        // String badPath = "logs" + File.separator + "app.log"; // 不推荐!
        // String worsePath = "logs/app.log"; // ❌ 硬编码,不跨平台!

        // ✅ 从相对路径转绝对路径(用于日志、临时文件)
        Path absoluteLog = logFile.toAbsolutePath();
        System.out.println("绝对路径:" + absoluteLog);

        // ==================== 2. 目录创建:安全、递归、幂等 ====================
        // ✅ createDirectories:递归创建所有父目录,已存在不报错(幂等)
        Files.createDirectories(LOG_DIR);
        Files.createDirectories(TEMP_DIR);
        System.out.println("✅ 日志目录和临时目录已创建(若不存在)");

        // ==================== 3. 文件写入:自动创建文件,指定编码 ====================
        String logContent = "【" + LocalDateTime.now() + "】用户登录成功,IP: 192.168.1.100\n";
        // ✅ write:自动创建文件,UTF-8 编码,安全写入
        Files.write(logFile, logContent.getBytes("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
        System.out.println("✅ 日志已追加写入:" + logFile);

        // ==================== 4. 文件读取:按行读取大文件(避免 OOM) ====================
        // ✅ readAllLines:适合小文件(<100MB)
        List<String> lines = Files.readAllLines(CONFIG_FILE);
        System.out.println("配置文件行数:" + lines.size());
        for (String line : lines) {
            if (line.trim().startsWith("db.url")) {
                String dbUrl = line.substring(line.indexOf("=") + 1).trim();
                System.out.println("数据库地址:" + dbUrl);
            }
        }

        // ✅ lines():流式读取大文件(推荐用于日志分析、CSV 处理)
        try (Stream<String> stream = Files.lines(logFile)) {
            long errorCount = stream.filter(line -> line.contains("ERROR"))
                                   .count();
            System.out.println("日志中错误数量:" + errorCount);
        } // ✅ 自动关闭流,避免句柄泄漏

        // ==================== 5. 文件复制与移动:安全、支持覆盖 ====================
        Path backupFile = LOG_DIR.resolve("app_backup.log");
        // ✅ copy:支持覆盖、保留属性
        Files.copy(logFile, backupFile, StandardCopyOption.REPLACE_EXISTING);
        System.out.println("✅ 日志已备份至:" + backupFile);

        // ✅ move:原子性移动(重命名),适合“写入完成”后切换文件
        Path finalLog = LOG_DIR.resolve("app_final.log");
        Files.move(backupFile, finalLog, StandardCopyOption.REPLACE_EXISTING);
        System.out.println("✅ 备份已重命名为最终日志:" + finalLog);

        // ==================== 6. 文件属性:获取权限、大小、时间 ====================
        BasicFileAttributes attrs = Files.readAttributes(logFile, BasicFileAttributes.class);
        System.out.println("文件大小:" + attrs.size() + " 字节");
        System.out.println("创建时间:" + attrs.creationTime());
        System.out.println("最后修改时间:" + attrs.lastModifiedTime());
        System.out.println("是否为目录:" + attrs.isDirectory());

        // ==================== 7. 删除文件/目录:安全、递归、容错 ====================
        // ✅ deleteIfExists:不存在不报错(推荐写法)
        Files.deleteIfExists(TEMP_DIR.resolve("temp_file.tmp"));
        System.out.println("✅ 临时文件已尝试删除(不存在也不报错)");

        // ✅ deleteRecursively:递归删除整个目录(如清理临时目录)
        Path tempDir = Paths.get("temp");
        if (Files.exists(tempDir)) {
            Files.walkFileTree(tempDir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file); // 删除文件
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir); // 删除空目录
                    return FileVisitResult.CONTINUE;
                }
            });
            System.out.println("✅ 临时目录 temp 已被彻底清理");
        }

        // ==================== 8. 判断文件是否存在、是否为符号链接 ====================
        Path symlink = Paths.get("config_link");
        if (Files.exists(symlink) && Files.isSymbolicLink(symlink)) {
            Path target = Files.readSymbolicLink(symlink);
            System.out.println("符号链接指向:" + target);
        }

        // ==================== 9. 创建临时文件/目录:用于缓存、上传、下载 ====================
        // ✅ createTempFile:自动生成唯一文件名,避免冲突
        Path tempFile = Files.createTempFile("upload_", ".tmp");
        System.out.println("✅ 临时上传文件:" + tempFile);

        // ✅ createTempDirectory:安全创建临时目录
        Path tempUploadDir = Files.createTempDirectory("upload_");
        System.out.println("✅ 临时上传目录:" + tempUploadDir);

        // ✅ 自动清理:生产环境必须在 finally 或 try-with-resources 中删除
        try {
            Files.write(tempFile, "临时数据".getBytes("UTF-8"));
            // ... 业务处理
        } finally {
            Files.deleteIfExists(tempFile); // ✅ 必须清理!
            Files.deleteIfExists(tempUploadDir); // ✅ 必须清理!
        }

        // ==================== 10. 检查文件权限(Linux/Unix 环境) ====================
        // ✅ 仅在类 Unix 系统有意义
        if (System.getProperty("os.name").toLowerCase().contains("nix") ||
            System.getProperty("os.name").toLowerCase().contains("mac")) {
            try {
                boolean canRead = Files.isReadable(logFile);
                boolean canWrite = Files.isWritable(logFile);
                System.out.println("日志文件可读:" + canRead + ",可写:" + canWrite);
            } catch (IOException e) {
                System.err.println("❌ 检查文件权限失败:" + e.getMessage());
            }
        }
    }
}

✅ 生产环境最佳实践总结(Files/Paths)

场景推荐做法禁用做法
路径构建Paths.get("a", "b", "c")"a/b/c" 字符串拼接
创建目录Files.createDirectories(path)new File(path).mkdirs()
写入文件Files.write(path, bytes, CREATE, APPEND)FileOutputStream 手动管理
读取大文件Files.lines(path) + try-with-resourcesFiles.readAllLines() 读取 GB 级文件
删除文件Files.deleteIfExists(path)file.delete() 不判断是否存在
删除目录Files.walkFileTree(...) 递归删除rmdir 命令(不可靠)
临时文件Files.createTempFile()手动命名 temp123.txt
编码始终使用 "UTF-8"使用默认编码(Charset.defaultCharset())

📌 致命警告:

  • 不要用 File!它在 Windows 上不支持 Unicode 文件名,且无异常分类。
  • 所有文件操作必须使用 try-with-resources 或 finally 清理,避免句柄泄漏(尤其在 Linux 服务器上)。
  • 临时文件必须主动删除,否则会占用磁盘空间,导致服务宕机。

✅ 二、对象安全操作:java.util.Objects —— 10 种生产级使用场景详解

Objects 是 Java 7 引入的防御性编程神器,它让你的代码不再被 NullPointerException 攻击,是团队代码质量的底线。

🌟 实战示例:Objects 的 10 种高价值用法(完整注释)

import java.util.*;
import java.util.Objects;

public class ObjectsSafetyExample {

    // ✅ 场景 1:构造器参数校验 —— 快速失败,明确错误信息
    public class UserService {
        private final String username;
        private final String email;

        public UserService(String username, String email) {
            // ✅ Objects.requireNonNull:参数不能为空,且提供清晰错误信息
            this.username = Objects.requireNonNull(username, "用户名不能为空");
            this.email = Objects.requireNonNull(email, "邮箱不能为空");

            // ✅ 额外校验:邮箱格式(可结合正则)
            if (!email.contains("@")) {
                throw new IllegalArgumentException("邮箱格式无效:" + email);
            }
        }

        public String getUsername() { return username; }
        public String getEmail() { return email; }
    }

    // ✅ 场景 2:重写 equals() —— 安全比较,避免 null 指针
    public class Product {
        private final String name;
        private final Double price;

        public Product(String name, Double price) {
            this.name = name;
            this.price = price;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Product)) return false;
            Product product = (Product) o;
            // ✅ Objects.equals:null 安全比较,推荐写法
            return Objects.equals(name, product.name) &&
                   Objects.equals(price, product.price);
        }

        @Override
        public int hashCode() {
            // ✅ Objects.hash:自动生成安全的 hashCode(自动处理 null)
            return Objects.hash(name, price);
        }
    }

    // ✅ 场景 3:对象属性打印 —— 避免 "null" 字符串污染日志
    public class Order {
        private String orderId;
        private String customerName;
        private String shippingAddress;

        public Order(String orderId, String customerName, String shippingAddress) {
            this.orderId = orderId;
            this.customerName = customerName;
            this.shippingAddress = shippingAddress;
        }

        @Override
        public String toString() {
            return "Order{" +
                    "orderId='" + Objects.toString(orderId, "未分配") + '\'' +
                    ", customerName='" + Objects.toString(customerName, "匿名用户") + '\'' +
                    ", shippingAddress='" + Objects.toString(shippingAddress, "未填写") + '\'' +
                    '}';
        }
    }

    // ✅ 场景 4:集合元素安全访问 —— 防止空指针
    public class OrderService {
        public String getCustomerNameFromOrder(Order order) {
            // ✅ Objects.nonNull:判断非空(与 requireNonNull 配合)
            if (Objects.nonNull(order) && Objects.nonNull(order.getCustomerName())) {
                return order.getCustomerName();
            }
            return "未知客户";
        }

        // ✅ 使用 Optional + Objects.nonNull(现代写法)
        public Optional<String> findCustomerName(Order order) {
            return Objects.nonNull(order) ? Optional.ofNullable(order.getCustomerName()) : Optional.empty();
        }
    }

    // ✅ 场景 5:Map 键值安全处理 —— 避免 NPE 在业务逻辑中传播
    public class ConfigManager {
        private final Map<String, String> config = new HashMap<>();

        public String getConfig(String key) {
            // ✅ Objects.requireNonNullElse:若为 null,返回默认值
            return Objects.requireNonNullElse(config.get(key), "default_value");
        }

        public String getConfigWithFallback(String key, String fallback) {
            // ✅ Objects.requireNonNullElseGet:延迟计算默认值(性能优化)
            return Objects.requireNonNullElseGet(config.get(key), () -> {
                System.out.println("⚠️ 配置 " + key + " 未设置,使用默认值");
                return fallback;
            });
        }
    }

    // ✅ 场景 6:方法返回值校验 —— 防止 null 从方法中逃逸
    public class DataProvider {
        public List<String> getActiveUsers() {
            // ✅ Objects.requireNonNull:确保返回值不为 null
            List<String> users = fetchUsersFromDB(); // 可能返回 null
            return Objects.requireNonNull(users, "获取用户列表失败,返回 null");
        }

        private List<String> fetchUsersFromDB() {
            // 模拟数据库查询失败
            return null; // 本应抛异常,但为演示
        }
    }

    // ✅ 场景 7:断言调试(仅开发环境)
    public class DebugHelper {
        public void validateUser(User user) {
            // ✅ Objects.requireNonNull:开发阶段快速失败,生产环境可关闭
            Objects.requireNonNull(user, "用户对象必须存在(调试断言)");
            // 生产环境应使用 @NonNull 注解 + Lombok 或静态分析工具
        }
    }

    // ✅ 场景 8:比较两个对象是否相等(非 null 安全)
    public class ComparatorHelper {
        public boolean areEqual(Object a, Object b) {
            // ✅ Objects.equals:推荐的相等判断,完全安全
            return Objects.equals(a, b);
        }

        public void test() {
            System.out.println(Objects.equals(null, null)); // true
            System.out.println(Objects.equals("abc", "abc")); // true
            System.out.println(Objects.equals("abc", null)); // false
            System.out.println(Objects.equals(null, "def")); // false
        }
    }

    // ✅ 场景 9:字符串安全拼接(结合 Objects.toString)
    public class LogFormatter {
        public String formatLog(String level, String message, Object... args) {
            StringBuilder sb = new StringBuilder();
            sb.append("[").append(level).append("] ");
            sb.append(message);
            if (args != null && args.length > 0) {
                sb.append(" | 参数:");
                for (Object arg : args) {
                    sb.append(Objects.toString(arg, "<null>")).append(", ");
                }
                sb.setLength(sb.length() - 2); // 删除最后的 ", "
            }
            return sb.toString();
        }
    }

    // ✅ 场景 10:链式调用中的安全保护(避免层层 null 判断)
    public class UserContext {
        private String userId;
        private String tenantId;

        public String getUserId() { return userId; }
        public String getTenantId() { return tenantId; }

        public static class Service {
            public String getTenantInfo(UserContext ctx) {
                // ✅ 传统写法:层层 if (ctx != null && ctx.getUserId() != null)
                // ❌ 冗长、易错、难维护

                // ✅ Objects.nonNull + Optional 链式写法(现代风格)
                return Optional.ofNullable(ctx)
                        .map(UserContext::getTenantId)
                        .filter(tenantId -> !tenantId.isBlank())
                        .orElse("DEFAULT_TENANT");
            }
        }
    }

    // ==================== 主方法:测试所有场景 ====================
    public static void main(String[] args) {
        // ✅ 场景 1:构造器校验
        try {
            new UserService(null, "test@example.com"); // 抛出:用户名不能为空
        } catch (IllegalArgumentException e) {
            System.out.println("✅ 构造器校验触发:" + e.getMessage());
        }

        // ✅ 场景 2:equals/hashCode
        Product p1 = new Product("iPhone", 999.99);
        Product p2 = new Product("iPhone", 999.99);
        Product p3 = new Product(null, null);

        System.out.println("p1 == p2:" + p1.equals(p2)); // true
        System.out.println("p1.hashCode() == p2.hashCode():" + (p1.hashCode() == p2.hashCode())); // true
        System.out.println("p3 toString:" + p3); // Product{name='null', price='null'} → 但 hashCode 仍安全

        // ✅ 场景 3:toString 安全
        Order order = new Order(null, null, null);
        System.out.println("订单信息:" + order);
        // 输出:Order{orderId='未分配', customerName='匿名用户', shippingAddress='未填写'}

        // ✅ 场景 4:安全访问
        OrderService os = new OrderService();
        System.out.println("客户名称:" + os.getCustomerNameFromOrder(null)); // 未知客户

        // ✅ 场景 5:Map 默认值
        ConfigManager cm = new ConfigManager();
        cm.config.put("db.url", "jdbc:mysql://localhost");
        System.out.println("数据库 URL:" + cm.getConfig("db.url")); // jdbc:mysql://localhost
        System.out.println("未配置项:" + cm.getConfig("nonexist")); // default_value
        System.out.println("带提示的默认值:" + cm.getConfigWithFallback("missing", "fallback_value"));

        // ✅ 场景 6:返回值校验
        DataProvider dp = new DataProvider();
        try {
            dp.getActiveUsers(); // 抛出:获取用户列表失败,返回 null
        } catch (NullPointerException e) {
            System.out.println("✅ 返回值校验触发:" + e.getMessage());
        }

        // ✅ 场景 7:调试断言
        DebugHelper dh = new DebugHelper();
        try {
            dh.validateUser(null); // 抛出:用户对象必须存在(调试断言)
        } catch (NullPointerException e) {
            System.out.println("✅ 调试断言触发:" + e.getMessage());
        }

        // ✅ 场景 8:相等判断
        ComparatorHelper ch = new ComparatorHelper();
        ch.test();

        // ✅ 场景 9:日志拼接
        LogFormatter lf = new LogFormatter();
        System.out.println(lf.formatLog("INFO", "用户登录", "张三", 28, true)); // [INFO] 用户登录 | 参数:张三, 28, true
        System.out.println(lf.formatLog("WARN", "权限不足", null)); // [WARN] 权限不足 | 参数:<null>

        // ✅ 场景 10:链式安全
        UserContext context = new UserContext();
        context.tenantId = "tenant-001";
        System.out.println("租户信息:" + UserContext.Service.getTenantInfo(context)); // tenant-001

        context.tenantId = null;
        System.out.println("租户信息(null):" + UserContext.Service.getTenantInfo(context)); // DEFAULT_TENANT
    }
}

✅ Objects 工具类使用黄金法则(生产规范)

场景推荐写法禁用写法
参数校验Objects.requireNonNull(param, "message")if (param == null) throw ...
equals 比较Objects.equals(a, b)a.equals(b)(可能 NPE)
hashCode 生成Objects.hash(fields...)手动拼接,忽略 null
字符串默认值Objects.toString(obj, "默认")obj != null ? obj : "默认"
Map 默认值Objects.requireNonNullElse(map.get(key), "default")map.containsKey(key) ? map.get(key) : ...
返回值保证return Objects.requireNonNull(result, "结果不能为 null")直接返回可能为 null 的对象
链式安全Optional.ofNullable(obj).map(...).orElse(...)多层 if (obj != null)

📌 团队强制规范建议:

  • 所有 public 方法参数,必须使用 Objects.requireNonNull 校验
  • 所有 equals()、hashCode()、toString(),必须使用 Objects 工具类
  • 所有日志输出对象,必须用 Objects.toString(obj, "<null>") 包裹
  • 所有配置项获取,必须用 Objects.requireNonNullElse 提供默认值

✅ 最终总结:JDK 工具类的“三座大山”

类别工具类作用生产必用
文件系统Files, Paths安全、跨平台、现代文件 I/O✅ 绝对必须
对象安全Objects防空指针、安全比较、默认值✅ 绝对必须

💡 记住这句话:
“一个没有使用 Objects.requireNonNull 的 Java 项目,是裸奔的;一个没有使用 Files 的 Java 项目,是活在 2005 年的。”


✅ 总结:JDK 工具类使用黄金法则

类别推荐工具禁用旧方式原因
集合操作Collections、Arrays手写循环更安全、高效、可读
日期时间LocalDateTime、DurationDate、SimpleDateFormat线程安全、API 清晰
字符串拼接StringJoiner、String.join()+ 拼接性能好、语义明确
并发 MapConcurrentHashMapHashtable、synchronizedMap性能提升 10x+
随机数SecureRandomRandom(安全场景)防预测、防攻击
文件操作Files、Pathjava.io.File更现代、支持 NIO、路径安全
格式化输出String.format()字符串拼接易维护、支持国际化

✅ 最佳实践建议(开发团队规范)

  1. 禁止使用 Date 和 SimpleDateFormat —— 全部替换为 java.time。
  2. 集合返回值一律返回不可变集合:Collections.unmodifiableList() 或 List.of()(JDK 9+)。
  3. 并发场景优先用 ConcurrentHashMap,避免 synchronized 锁。
  4. 文件操作统一使用 java.nio.file.Files,路径用 Path。
  5. 随机数用于安全令牌时,必须用 SecureRandom。
  6. 字符串拼接超过 3 个变量,用 StringJoiner 或 String.format()。

✅ 下一步学习建议

  • 学习 Stream API(java.util.stream):函数式集合处理
  • 学习 Optional<T>:替代 null 判断
  • 学习 CompletableFuture:异步编程
  • 学习 java.util.concurrent.atomic:原子类(AtomicInteger、AtomicReference)

如果你希望我为你系统讲解 Java 8+ Stream API 的实战用法 或 如何用 Optional 替代空指针判断,欢迎继续提问,我会为你提供企业级代码范例和避坑指南。

深入探索JDK17:从基础到实战的全方位指南 JDK17专栏全面解析Java最新LTS版本的特性与应用。内容涵盖:基础安装指南(Windows/Linux)、新语法特性实战(密封类、模式匹配等)、性能调优策略(内存管理、线程优化)、安全机制(加密算法、数字签名)以及微服务开发实践(Spring Boot集成、RESTful API)。通过丰富的代码示例和分步教程,帮助开发者掌握JDK17在企业级应用中的核心技能,解决实际开发问题。专栏适合Java初学者及进阶开发者系统学习JDK17新特性。 阅读详情

相关推荐

JDK1.8新特性详解与实战代码示例

Java自1995年发布以来,经历了多次版本迭代,而JDK 1.8(又称Java 8)无疑是其中最具里程碑意义的版本之一。它不仅引入了Lambda表达式、Stream API、默认方法、新的日期时间API等核心特性,还从语言层面提升了函数式编程的支持,显著增强了Java的表达力与开发效率。在本章中,我们将了解JDK 1.8诞生的技术背景与设计初衷,探讨其在Java生态系统中的战略地位,并初步认识其核心新特性及其对现代Java开发的深远影响。Lambda 表达式必须作用于函数式接口。

weixin_35754676的博客 976

jdk工具集合汇总

jvisualvm:jvisualvm是一个全功能的Java性能监控和分析工具,提供了各种监控和分析功能,包括内存使用情况、线程状态、垃圾回收、CPU使用等。它读取源代码中的特殊注释(Javadoc注释),并根据注释生成HTML格式的文档,描述类、接口、方法和字段的用法和说明。这些工具提供了丰富的功能,涵盖了Java应用程序的开发、调试、性能分析和管理等方面。jar:jar命令用于创建和管理Java归档文件(JAR文件),它可以将多个类文件、资源文件和库文件打包到一个JAR文件中,并支持压缩和解压缩操作。

三朝看客 2180

java常用的工具类整理28个

java常用的工具类整理28个java常用的工具类整理28个java常用的工具类整理28个

JAVA JDK 常用工具类和工具方法

Pair 使用示例(一般使用里面的Of方法去初始化值)/*过滤出,校验成功和失败的数据*/} else {});} else {/*过滤数据,失败的数据要有失败原因 -每一条数据一个Pair*/} else {pairsList.add(Pair.of(a, "数据小于5"));});} else {/*过滤出,校验成功和失败的数据*//*过滤数据,失败的数据要有失败原因--每一条数据一个Pair*/

qq_49662572的博客 1512

28个java常用的工具类

java工具类,包含了字符串类型,数据类型,MD5,日期时间类型,文件上传工具类,正则表达式帮助类等28个java开发的常用工具。

jdk8工具包

jdk8-windowsx64工具包,主要是想留档,现在Oracle下载需要登录账号了,而且听说要收费了

JDK中的常用工具类

JDK中内置了很多常用的工具类,且多以“s”结尾,如:集合工具类Collections,数组工具类Arrays,对象工具类Objects,文件工具类Files,路径工具类Paths,数学工具类Maths;但也有一些不是以“s”结尾的工具类,如TimeUnit和System。 下面就简...

1570

VSCode终端打不开?3分钟搞定Windows下Terminal配置(附最新JSON设置方法)

本文针对Windows系统下VSCode终端无法启动的常见问题,提供了详细的诊断与解决方案。核心在于更新已弃用的旧配置,采用最新的JSON设置方法,通过定义`terminal.integrated.profiles.windows`和指定`terminal.integrated.defaultProfile.windows`,快速修复并优化终端配置,实现三分钟内恢复正常使用。

flower的专栏 740

java常用工具类说明

Collections.synchronizedCollection(Collection c, Object mutex) 指定mutex对象作为同步锁,将集合转换为线程安全的同步集合。Arrays.deepToString(Object[] a)方法内部调用了a.toString()。由于JDK1.5引入了泛型,采用该方法,保证运行期集合中增加的元素只能是指定的类型。Collections.sort()最终调用的是Arrays.sort()进行排序。Collections.sort()的源码。

weixin_51289856的博客 436

IAR9.X半主模式异常解析:为何硬件复位后仍陷调试状态?

本文深入解析了IAR 9.X半主模式异常问题,探讨了硬件复位后MCU仍陷调试状态的原因及解决方案。通过分析半主模式工作机制,提供了禁用半主功能、重写低级IO函数等具体方法,并给出了版本兼容性处理和调试与量产配置分离的优化建议,帮助开发者有效解决复位异常问题。

oo7890的博客 604

Windows Server 2008 R2装不上VMware Tools?别急,手动安装驱动补丁的保姆级教程来了

本文提供了Windows Server 2008 R2手动安装VMware Tools驱动补丁的详细教程,解决驱动签名验证失败问题。通过获取特定补丁文件、创建安装介质、挂载虚拟机并安装补丁等步骤,帮助用户顺利完成VMware Tools安装,提升虚拟机功能与性能。

weixin_28335283的博客 467

Java基础 {JDK给我们带的工具类(Object类,包装类,String类,计算类,时间类,System类,Math类)}

文章目录 JDK给我们带的工具类 Object类 object是所有类的父类 getClass()方法 hashCode()方法 toString()方法----重写 equals()方法----重写 比较的是0x11和0x22 包装类---堆区 包装类对应 Integer---相当于对象 两种类型可以互相转换 String类 垃圾回收机制 cahrAt()方法 contains()方法 toCharArray()方法 indexOf()方法 length()方法 t

m0_60237095的博客 1231

PSM倾向匹配详细步骤和程序

目录1.安装psmatch2统计包。2.数据准备3.数据分析及命令解读4.结果解读4.1模型拟合结果,此处无太多实际意义。4.2试验组可匹配的观测概览,按照命令中设定的匹配规则,试验组有8例患者未能匹配到合适对照。4.3结果解读的重点应该是对stata新生成的中间变量的解读。4.4均衡性检验结果4.5匹配结果的图示化5.Stata命令汇总最后留下两个问题给大家思考:题目 试验设计中,匹配的目的在于确保干预效应估计是建立在可比个体之间的不同结果的基础上。最简单的匹配方式是将干预组和对照组中协变量值相同的两个个

平平淡淡,戒急用忍,一生学闭嘴。 5万+

JDK中不能继承的类:final类的作用与意义

在Java编程中,有些类被标记为`final`,这意味着这些类不能被其他类继承。这就像是一个家族中的某个秘方,你只想让这个秘方保持原样,不希望其他人在你的基础上进行改动。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 6393

华为OD机试真题 新系统 - 8位LED控制器 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 1970

Codex 100个真实案例 - 用AI做股票K线分析工具(技术指标全自动)

本案例将用 Codex 从零搭建一个完整的股票 K 线分析工具。通过自然语言驱动,我们让 AI 自动完成股票数据获取(akshare)、K 线图绘制(mplfinance + ECharts)、技术指标计算(MA/EMA/MACD/RSI/KDJ/布林带)、买卖信号提示(金叉/死叉、超买超卖)、多股对比分析、Web 可视化界面(Flask + ECharts)、PDF 报告生成以及定时监控邮件推送等全套功能。全程用自然语言指令驱动 Codex,零手写代码实现专业级量化分析平台!

yueyeguzhuo的专栏 863

Java开发经验——Java开发常用工具类实战总结

本文介绍了Java开发中常用的工具类,包括Apache Commons Collections的SetUtils、Google Guava的Sets、Apache Commons Lang的ArrayUtils等,以及它们在集合操作、数组操作、字符串处理、JSON处理等方面的应用。文章还涉及了Optional类、Money工具类、JDK流式函数等,旨在提高Java开发效率和代码质量。

庄小焱 1851

Fabric V2.5 通用溯源系统——使用Hyperledger Caliper压力测试

Caliper是一款测试区块链性能的工具,支持Hyperledger Fabric、Ethereum等,支持丰富的测试配置参数,测试完成后将直接输出报告,相较于tape更加专业,但是配置稍微有些复杂。本文将一步一步配置Caliper以测试Fabric V2.5 通用溯源系统中的注册用户、查询用户、农产品上链、农产品查询的区块链性能。

TrueTechLabs 官方博客 1395

【Java】常用工具类 这些很常用噢~

本文系统讲解 Java 中最常用的工具类,包括 Math、Arrays、System、Objects、Scanner、Random、BigDecimal、包装类以及日期时间类。每个工具类都配有核心方法说明和代码示例,适合初学者快速上手

xingzi1019的博客 423

hwasan实例分析踩内存之一:camx进程stack tag-mismatch的三种解决方案

hwasan实例分析踩内存之一:camx进程stack tag-mismatch的三种解决方案。

1291

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Jdk常用工具

1.工具概述 作为一个java程序员,最基本的要求就是用java语言编写程序,并能够在jvm虚拟机上正常运行,但是在实际开发过程中,我们所有的程序由于各种各样的原因,并不是总能够正常运行,经常会发生故障或者程序的性能低下等问题,此时我们就需要借助于一些jdk提供的工具来定位问题、分析问题并给出合适的解决方案。 jdk给程序员提供的辅助工具都存放在bin目录下,见下图: jdk提供的这些...

qq_29860591的博客 3400

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

JDK 21最常用工具类总结及解析:提升开发效率的利器

本文将系统性地梳理和解析JDK 21中最常用、最实用的工具类及其新特性。

一起探索IT的世界 1353

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【JDK内置工具】常用工具和实战指令

作为Java开发者,JDK内置工具是我们日常开发的"瑞士军刀"。唐叔将通过本文给热爱学习的小伙伴们详细介绍jps、jstack、jmap、jstat等核心工具的使用场景和实战技巧,帮你快速定位内存泄漏、线程死锁等疑难杂症。掌握这些工具,让你从"API调用工程师"进阶为真正的Java问题解决专家!

唐叔学习中... 1728

Java16个原子类介绍-基于JDK8

前言 emmmm,在写文章前我也翻阅了好多资料和书籍,其实大家在对原子类方法的使用介绍基本都没问题,但是对于java中原子类的个数是五花八门,下面我就把自己都认知和书籍资料结合起来给大家简单都介绍下java中原子类的应用。 参考文献 《Java并发编程的艺术》 正文 关于原子类个数说明 在JDK7包括7之前,java原子类有12个,图片如下,有些资料说有13个,多出来的是 Atomic...

晏霖/胖虎的博客 2万+

#Java-JDK7、8的时间相关类,包装类

包装类是基本数据类型对应的引用数据类型(对象)使用包装类是为了数据的统一,因为只有引用数据类型才能使用集合,也只有类才可以使用Object来接收数据//代码使用一个类的成员变量来记录数值操作数据的方法。

2302_80203877的博客 1077

Spring常用工具类

文章目录一、内置工具类1、断言2、对象、数组、集合2.1 ObjectUtils2.2 StringUtils2.3 CollectionUtils3、文件、资源、IO 流3.1 FileCopyUtils3.2 ResourceUtils3.3 StreamUtils4、反射、AOP4.1 ReflectionUtils4.2 AopUtils4.3 AopContext4.4 AOP举例二、第三方工具类 一、内置工具类 内置工具类一般位于org.springframework.util下 1、断言 断

Shawn的个人博客 5297
上一篇: String 常用方法总揽(按功能分类)
下一篇: Java 内部类和内部枚举的深入理解和示例参考
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值