基础类 null 问题源于默认不拒绝 null 但业务不容忍,需用 requirenonnull、isempty、getordefault 等主动防御;时间类勿混用 date 与 localdatetime;http 客户端须配超时与连接池;json 反序列化泛型必须显式传 typereference。

String、List、Map 这些基础类,为什么总在 null 和空判断上翻车
因为 Java 的集合和字符串默认不拒绝 null,但业务逻辑里又几乎从不希望它出现。比如 list.get(0) 返回 null,你直接调用 .length() 就抛 NullPointerException;又比如 map.get("key") 返回 null,你误以为 key 不存在,其实可能是 value 就是 null。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
Objects.requireNonNull()显式拦截参数级 null,比事后 try-catch 更早暴露问题 -
Collection.isEmpty()比size() == 0安全,且语义更清晰;但注意它对null集合本身会 NPE,得先判空 - 从 Guava 引入
Lists.newArrayList()或ImmutableList.of(),避免手写new ArrayList()后忘初始化或被外部修改 - Map 场景优先考虑
Map.getOrDefault(key, defaultValue),绕过 null 判断分支
LocalDateTime vs Date:时间处理选错类,上线后时区/格式全乱
Date 是可变的、带毫秒偏移的遗留类,LocalDateTime 是不可变的、无时区的纯日期时间——它们根本不是替代关系,混用必出问题。比如把 LocalDateTime.now() 直接塞进 JDBC PreparedStatement,驱动会默默转成当天 00:00 UTC 时间,而不是你本地时间。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 数据库字段是
TIMESTAMP WITH TIME ZONE(如 PostgreSQL)或需要跨时区一致,用ZonedDateTime或OffsetDateTime - 仅存日期+时间(如“会议开始时间”),且不涉及时区转换,用
LocalDateTime;但入库前必须通过Timestamp.valueOf()转换,别依赖 JPA 自动映射 - 老项目还在用
Date?至少用Date.from(Instant)构造,别用已废弃的new Date(year, month, day) - 日志打印时间统一走
DateTimeFormatter.ISO_LOCAL_DATE_TIME,别拼字符串,避免线程不安全的SimpleDateFormat
HttpClient、OkHttp、RestTemplate:发个 HTTP 请求,怎么选不踩重试/连接池/超时坑
不是越新越好。Spring Boot 2.3+ 默认禁用 RestTemplate,但它在已有 Spring 生态里仍最省心;HttpClient(Apache)稳定但配置项多;OkHttp 性能好,但默认开启连接复用,若没配 connectionPool 限流,高并发下可能耗尽文件描述符。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
RestTemplate?必须手动 setsetConnectTimeout和setReadTimeout,它默认不设超时,卡死线程不报错 - 用
OkHttp?务必配ConnectionPool(maxIdleConnections=5, keepAliveDuration=5, TimeUnit.MINUTES),否则 idle 连接无限堆积 - 用
HttpClient?别用HttpClients.createDefault(),它不复用连接;改用HttpClients.custom().setConnectionManager(...),并启用setConnectionTimeToLive - 所有客户端都建议包装一层 retry 逻辑,但别在底层 HTTP client 里开重试(如 OkHttp 的
RetryAndFollowUpInterceptor),容易和上层业务重试叠加
Gson、Jackson、Fastjson:JSON 序列化一跑就报错,到底是类型擦除还是注解没生效
根本矛盾在于:Java 泛型运行时擦除,而 JSON 反序列化需要知道真实类型。Gson 默认不支持泛型集合(如 List<foo></foo>),Jackson 需要 TypeReference,Fastjson 2.x 已放弃兼容老版 JSON.parseObject(json, clazz) 写法。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- Gson 反序列化泛型用
gson.fromJson(json, TypeToken.getParameterized(List.class, Foo.class).getType()),别偷懒传List.class - Jackson 推荐用
ObjectMapper.readValue(json, new TypeReference<list>>() {})</list>,注意末尾的{}是匿名子类,不能省 - Fastjson 1.x 有安全漏洞,2.x 不兼容 1.x 注解(如
@JSONField改成@JSONCreator),升级必须全量测试 - 所有库都默认忽略 null 字段,若需输出
"field": null,Gson 要setSerializeNulls(),Jackson 要setSerializationInclusion(JsonInclude.Include.NON_NULL)反向设置
类型擦除不是 bug,是 Java 语言特性;所有 JSON 库都在这个限制下做妥协。谁封装得更透明,谁就少写一行 TypeReference ——但这行代码,漏了就是线上解析失败。










