java是静态类型语言,变量声明必须显式写类型;局部变量可用var(jdk10+且初始化可推断)、泛型构造器可用;字符串比较用equals()而非==;循环拼接用stringbuilder;异常处理应精准捕获并用try-with-resources。

变量声明不写类型,以为 Java 和 JavaScript 一样能推导
Java 是静态类型语言,int、String、List<string></string> 这些类型必须显式写出来。新手常照着 Python 或 JS 习惯写 name = "Alice",结果编译直接报错 error: cannot find symbol。
真正能省略类型的只有两种情况:局部变量用 var(仅 Java 10+,且只限初始化时能明确推断的场景),以及泛型构造器的类型推导(如 new ArrayList<string>()</string> 可简写为 new ArrayList())。
-
var不能用于字段、方法返回值、参数——这些地方类型必须写死 -
var list = new ArrayList()推导出的是ArrayList<object></object>,不是ArrayList<string></string>,后续加字符串会编译失败 - 用
var前先确认 JDK 版本:java -version输出至少是10
字符串拼接滥用 +,没意识到 StringBuilder 的存在
在循环里写 result += str 看似简洁,实际每次都会新建 String 对象,时间复杂度是 O(n²)。JVM 不会自动优化这种场景,尤其当循环上千次时,性能暴跌且 GC 压力大。
真正该用 + 的只有编译期可确定的拼接,比如 "Hello" + "World";运行时拼接一律考虑 StringBuilder(单线程)或 StringBuffer(多线程但慢)。
立即学习“Java免费学习笔记(深入)”;
- 循环内拼接:先声明
StringBuilder sb = new StringBuilder(),循环中调用sb.append(str),最后sb.toString() - 别在循环外反复
new StringBuilder()再丢弃——复用同一个实例更省 -
String.join(",", list)比手写循环拼接更安全、更简洁,适合已知分隔符的集合拼接
用 == 比较字符串内容,结果逻辑总是错
== 比较的是两个引用是否指向同一块内存地址,而字符串内容相等要用 .equals()。新手常写 if (str == "hello"),结果 null 安全没保障、字面量池外的对象永远不等。
更糟的是,这个错误有时“碰巧”通过:比如两个字面量 "hello" == "hello" 成立,但换成 new String("hello") == "hello" 就是 false,极易埋下偶发 bug。
- 统一用
"hello".equals(str),把字面量放前面,避免str为null时抛NullPointerException - 需要忽略大小写用
.equalsIgnoreCase(),别自己转小写再比 - 判断空字符串优先用
str.isEmpty()或str.isBlank()(Java 11+),别用str.equals("")
异常处理只写 catch (Exception e),却不管资源泄漏和业务语义
捕获 Exception 等于把 NullPointerException、ArrayIndexOutOfBoundsException 这类编程错误也吞掉,掩盖真实问题。同时,文件流、数据库连接这类资源若没显式关闭,哪怕写了 catch 也会泄漏。
Java 的异常分两类:受检异常(IOException 等)必须处理;非受检异常(RuntimeException 子类)代表程序缺陷,不该被常规 catch。
- 打开资源就用 try-with-resources:
try (FileInputStream fis = new FileInputStream("a.txt")) { ... },JVM 自动关 - 只捕获你明确知道如何恢复的异常,比如
catch (FileNotFoundException e)后给默认配置 - 绝不要
catch (Exception e) { e.printStackTrace(); }—— 日志没级别、没上下文、还吃掉异常
最常被跳过的其实是「异常链」:抛出自定义异常时,记得用 throw new BusinessException("xxx", e) 把原始异常传进去,否则堆栈信息断层,排查时根本找不到根因。









