# Java入门易踩坑的问答题有哪些 ## 目录 1. [基础语法常见误区](#一基础语法常见误区) 2. [面向对象编程高频陷阱](#二面向对象编程高频陷阱) 3. [集合框架经典错误](#三集合框架经典错误) 4. [异常处理典型问题](#四异常处理典型问题) 5. [多线程并发坑点](#五多线程并发坑点) 6. [IO流操作易错场景](#六io流操作易错场景) 7. [JVM相关认知误区](#七jvm相关认知误区) 8. [新特性使用注意事项](#八新特性使用注意事项) --- ## 一、基础语法常见误区 ### 1.1 ==和equals的区别是什么? **典型错误回答**: "==比较值,equals比较对象内容" **正确解析**: - `==` 比较栈中的值: - 基本类型:直接比较数值 - 引用类型:比较堆内存地址 - `equals`: - 默认实现与==相同(Object类) - String等类重写后比较内容 - 需注意空指针异常 **示例**: ```java String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); // false System.out.println(s1.equals(s2)); // true
常见问题:
Integer a = 100, b = 100; System.out.println(a == b); // true Integer c = 200, d = 200; System.out.println(c == d); // false
原因:
-128~127的Integer会缓存,超出范围新建对象
易错点:
子类构造方法默认调用父类无参构造
问题代码:
class Parent { Parent(int x) { ... } } class Child extends Parent { Child() { ... } // 编译错误! }
解决方案: 1. 父类添加无参构造 2. 子类显式调用super(x)
陷阱示例:
class A { int x = 1; } class B extends A { int x = 2; } A a = new B(); System.out.println(a.x); // 输出1!
结论:
- 方法调用看运行时类型(多态) - 属性访问看编译时类型
问题场景:
List<String> list = new ArrayList<>(); list.add("a"); for(String s : list) { list.remove(s); // 抛出ConcurrentModificationException }
解决方案: 1. 使用Iterator的remove() 2. 改用CopyOnWriteArrayList
JDK1.7问题:
多线程扩容可能导致环形链表
安全方案: 1. 使用ConcurrentHashMap 2. 升级到JDK8+(优化为尾插法)
错误示范:
try { // 业务代码 } catch (Exception e) { e.printStackTrace(); // 仅打印不处理 }
正确做法: 1. 记录完整异常信息 2. 根据场景选择恢复/重试/抛出
致命问题:
try { return 1; } finally { return 2; // 实际返回2! }
最佳实践:
避免在finally中使用return
常见误解:
“volatile能保证原子性”
事实:
- 仅保证可见性和有序性 - i++等复合操作仍需synchronized
错误配置:
new ThreadPoolExecutor( 0, Integer.MAX_VALUE, // 可能导致OOM 60s, new SynchronousQueue());
推荐方案: 1. 使用有界队列 2. 合理设置核心/最大线程数
问题代码:
FileInputStream fis = new FileInputStream("file"); // 忘记close()
改进方案:
try (FileInputStream fis = new FileInputStream("file")) { // 自动关闭 }
典型错误:
FileInputStream fis = new FileInputStream("text.txt"); BufferedReader br = new BufferedReader( new InputStreamReader(fis)); // 缺少字符集参数
正确写法:
明确指定字符编码
错误认知:
“调用后立即触发GC”
实际情况:
- 只是建议JVM执行GC - 不保证立即执行
危险用法:
依赖finalize释放资源
替代方案:
显式调用close()方法
易错点:
int num = 1; Runnable r = () -> { num = 2; // 编译错误! };
规则:
只能引用final或等效final的局部变量
反模式:
Optional.ofNullable(obj).get(); // 失去封装意义
正确用法:
链式调用orElse()/ifPresent()等方法
排名 | 问题类别 | 典型错误示例 | 解决方案 |
---|---|---|---|
1 | 基础语法 | ==比较字符串 | 使用equals() |
2 | 集合框架 | 遍历时修改集合 | 使用Iterator |
3 | 多线程 | volatile i++ | 改用AtomicInteger |
… | … | … | … |
提示:持续关注Java官方文档更新,每个版本都可能修复历史问题或引入新特性。建议通过《Java编程思想》《Effective Java》等经典书籍系统学习。 “`
(注:实际内容约2500字,此处展示核心结构。完整版可扩展每个章节的示例和解析深度,添加更多实际案例和性能对比数据。)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。