Java 高级编程技巧

企业级开发中最实用、高频的 Java 高级技巧,覆盖代码优化、性能、并发、设计、JVM、工具六大方向,全是能直接落地的干货,适合进阶学习。

一、代码优雅与设计技巧

1. 巧用 Lambda + Stream 替代循环(可读性爆炸)

90% 的遍历、过滤、映射都能用 Stream 一行写完,代码更简洁、无冗余变量。

// 需求:筛选出成年人,提取姓名并去重排序
List<String> names = userList.stream()
        .filter(u -> u.getAge() >= 18)
        .map(User::getName)
        .distinct()
        .sorted()
        .collect(Collectors.toList());

进阶技巧parallelStream() 并行流(大数据量提升效率),但注意线程安全

2. Optional 杜绝空指针(Java 8+ 必备)

不要手写 if (obj == null),用 Optional 优雅处理空值:

// 安全获取嵌套属性,不存在直接返回默认值
String city = Optional.ofNullable(user)
        .map(User::getAddress)
        .map(Address::getCity)
        .orElse("未知城市");

// 空值时执行逻辑
Optional.ofNullable(user).ifPresent(u -> log.info("用户存在"));

3. 函数式接口自定义 Lambda(高阶用法)

自己定义接口,让代码支持传递行为,而非仅传递数据:

@FunctionalInterface
interface CheckHandler<T> {
    boolean check(T t);
}

// 通用校验方法
public static <T> boolean validate(T obj, CheckHandler<T> handler) {
    return handler.check(obj);
}

// 使用:灵活传入校验逻辑
boolean valid = validate(user, u -> u.getAge() > 18);

4. 建造者模式 + Lombok 告别臃肿构造器

@Data
@Builder
public class User {
    private Long id;
    private String name;
}

// 链式调用,可读性拉满
User user = User.builder().id(1L).name("张三").build();

二、并发编程高级技巧(面试 + 实战核心)

1. ThreadLocal 安全存储线程上下文

用于存储登录用户、请求 ID,线程隔离,无并发安全问题:

private static final ThreadLocal<User> USER_HOLDER = new ThreadLocal<>();

// 存值
USER_HOLDER.set(user);
// 取值
USER_HOLDER.get();
// 必须手动移除!防止内存泄漏
USER_HOLDER.remove();

关键:线程池场景下必须 remove,否则会导致数据错乱。

2. 线程池必须手动创建,拒绝 Executors

Executors 内置线程池会导致 OOM,手动创建才是规范:

ExecutorService executor = new ThreadPoolExecutor(
        5,          // 核心线程
        10,         // 最大线程
        60L,        // 空闲时间
        TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(100),  // 有界队列(关键)
        new ThreadFactoryBuilder().setNameFormat("my-pool-%d").build(),
        new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);

3. CompletableFuture 异步编排(秒杀、接口聚合神器)

支持多任务异步、串行、并行、依赖执行,比 Future 强 10 倍:

// 同时查询用户+订单,最后合并结果
CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() -> userService.getById(id));
CompletableFuture<Order> orderFuture = CompletableFuture.supplyAsync(() -> orderService.getByUserId(id));

CompletableFuture.allOf(userFuture, orderFuture).join();

User user = userFuture.get();
Order order = orderFuture.get();

4. 锁优化技巧

  • 优先用乐观锁(CAS / 版本号),无锁竞争,性能更高
  • 锁粒度尽可能小:不要锁整个方法,只锁共享变量
  • Lock 替代 synchronized:支持超时、中断、公平锁

三、性能优化高级技巧

1. 集合使用规范(避免 90% 的性能坑)

  • 初始化集合指定容量,减少扩容损耗
// 预估 100 条数据,直接指定容量
List<User> userList = new ArrayList<>(100);
Map<String, Object> map = new HashMap<>(16);
  • 大数据量用 ArrayList 而非 LinkedList
  • 频繁删除 / 插入用 ArrayDeque 替代 LinkedList

2. 字符串优化

  • 循环中禁止使用 + 拼接字符串,用 StringBuilder
  • 静态常量字符串直接定义为 public static final

3. 避免频繁创建对象(池化思想)

  • 线程池、连接池、对象池(如 OkHttp 连接池)
  • 大对象、高频对象复用,减少 GC 压力

四、JVM 与故障排查技巧

1. 必知的 JVM 参数(生产环境标配)

-Xms4g -Xmx4g        # 堆内存固定,避免扩容
-XX:+UseG1GC         # G1 垃圾收集器(现代 JDK 默认)
-XX:PrintGCDetails   # 打印 GC 日志

技巧Xms = Xmx 性能最优。

2. 快速排查故障命令

  • 查看 CPU 飙高:top + jstack
  • 查看内存泄漏:jmap 导出堆 dump + MAT 工具分析
  • 查看 GC 情况:jstat -gc 进程ID

五、反射 & 动态代理(框架底层核心)

1. 反射高效用法

  • 缓存反射获取的 Method/Field,不要重复获取
  • setAccessible(true) 跳过访问检查,提升速度

2. JDK 动态代理(AOP 底层原理)

面向接口代理,无侵入增强逻辑:

public static <T> T createProxy(T target) {
    return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            (proxy, method, args) -> {
                System.out.println("前置增强");
                Object result = method.invoke(target, args);
                System.out.println("后置增强");
                return result;
            }
    );
}

六、工程化 & 高效开发技巧

1. 统一异常处理(SpringBoot)

@RestControllerAdvice 全局捕获异常,代码无 try-catch:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(RuntimeException.class)
    public Result handleException(RuntimeException e) {
        return Result.fail(e.getMessage());
    }
}

2. 函数式接口 + 注解简化重复代码

校验、日志、事务等通用逻辑抽成公共方法,一行调用。

3. 工具类天花板:HuTool

替代手写工具类,文件、加密、日期、HTTP 全能支持:

// 一行加密
String md5 = SecureUtil.md5("123456");
// 一行日期格式化
String date = DateUtil.format(new Date(), "yyyy-MM-dd");

总结

  1. 代码层:Stream + Lambda + Optional + Lombok 让代码极简优雅
  2. 并发层:手动线程池 + CompletableFuture + ThreadLocal 稳、快、安全
  3. 性能层:集合指定容量、池化、避免创建大对象
  4. 工程层:全局异常、动态代理、工具库 提升开发效率
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值