文章目录
〇、写在前面:为什么你的Java总像浆糊?
刚入坑的兄弟肯定遇到过这种情况(疯狂点头吧?):看代码每行都认识,连起来就懵逼;写个循环能报5种错;对象创建了十几次内存直接炸… 这都是因为地基没打牢啊老铁!今天就带你们把Java基础揉碎了重组,包你醍醐灌顶!
一、八大基本类型:别再说int是对象了!
1.1 数字三剑客(必考重点!)
int age = 25; // 4字节(-21亿~21亿)
double price = 9.99; // 8字节(默认小数类型)
long distance = 384400L; // 加L防止被认成int
敲黑板:1.0
默认是double!想用float得写成1.0f
(多少人在这个坑里摔过?评论区举手!)
1.2 布尔值の哲学
boolean isRain = true;
if (isRain = false) { // 注意!!这里应该是==
System.out.print("带伞");
}
这个经典错误能坑死80%新手(编译居然不报错!!!)记住:单等号是赋值,双等号才是比较!
二、对象世界的生存法则(OOP核心)
2.1 对象诞生记
// 错误示范!直接new接口
// List<String> list = new List<>();
// 正确姿势(多态の奥义)
List<String> list = new ArrayList<>();
看到没?左边是接口类型,右边是实现类(ArrayList/LinkedList随便换),这就是传说中的面向接口编程啊兄弟们!
2.2 构造方法の骚操作
public class Student {
private String name;
// 无参构造(不写的话,子类可能原地爆炸!)
public Student() {
this("默认姓名"); // 调用有参构造
}
public Student(String name) {
this.name = name;
}
}
划重点:如果类中写了有参构造,系统就不再自动生成无参构造了(多少人在继承时被这个坑哭?)
三、集合框架:别再用for循环删元素了!
3.1 ArrayList的死亡陷阱
List<Integer> nums = new ArrayList<>(Arrays.asList(1,2,3,4));
// 错误删除方式(会漏删!)
for (int i=0; i<nums.size(); i++) {
if(nums.get(i)%2 ==0) {
nums.remove(i); // 删除后索引错位!!!
}
}
// 正确姿势(倒着删)
for (int i=nums.size()-1; i>=0; i--) {
if(nums.get(i)%2 ==0) {
nums.remove(i);
}
}
血的教训:遍历时修改集合必须用迭代器(Iterator)或者倒序操作!(有多少人曾经在这里debug到凌晨3点?)
3.2 HashMap的哈希战争
Map<String, Integer> scores = new HashMap<>();
scores.put("张三", 90);
scores.put("李四", 85);
// 遍历标准姿势(entrySet效率最高)
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
特别注意:JDK8的HashMap底层是数组+链表+红黑树(面试必问!),加载因子默认0.75,扩容2倍…
四、异常处理:别只会printStackTrace了!
4.1 异常分类图鉴(重要等级⭐⭐⭐⭐⭐)
Throwable
/ \
Error Exception
/ \
IOException RuntimeException
- Error:系统级错误(如OutOfMemoryError)-- 不用处理
- Checked Exception:必须try-catch(如IOException)
- Unchecked Exception:可处理可不处理(如NullPointerException)
4.2 自定义异常实战
// 继承RuntimeException就是非检查型异常
public class MyException extends RuntimeException {
public MyException(String message) {
super("自定义异常:" + message);
}
}
// 使用姿势
if (param == null) {
throw new MyException("参数不能为空!");
}
重点提醒:不要用异常做业务逻辑控制!性能杀手!(见过有人用异常实现循环终止的吗?评论区开开眼)
五、JVM极简课堂:其实你每天都在用!
5.1 内存模型三原色
┌──────────────┐
│ 方法区 │ 存类信息、静态变量
├──────────────┤
│ 堆Heap │ 对象实例所在地(GC主战场)
├──────────────┤
│ 虚拟机栈 │ 方法调用栈帧(局部变量在这里)
├──────────────┤
│ 本地方法栈 │ Native方法
├──────────────┤
│ 程序计数器 │ 当前执行位置
└──────────────┘
灵魂拷问:String str = new String(“abc”) 创建了几个对象?(答案在文末彩蛋)
六、避坑指南:前辈们用头发换的经验
- ==和equals:基本类型用==,对象比较用equals(String比较尤其要注意!)
- 字符串拼接:循环内别用+号拼接!用StringBuilder(性能差10倍+)
- BigDecimal:金钱计算必须用这个!double会丢精度(血泪教训!)
- 资源关闭:使用try-with-resources自动关流(JDK7+特性真香)
- 日志规范:别再用System.out了!SLF4J+Logback搞起来
终极彩蛋:那个经典的JVM问题
new String("abc")
实际上会创建1或2个对象:
- 如果常量池没有"abc",先在常量池创建,再在堆创建
- 如果已有"abc",只在堆创建新对象
(没想到吧?这就是为什么阿里规约强制要求String s = "abc"
的写法!)
看到这里的小伙伴,恭喜你已经打败全国80%的Java初学者!但记住:看十遍不如敲一遍(别光收藏不练习啊喂!)。准备好迎接更多硬核知识轰炸了吗?咱们下期《JVM调优从入门到改行》见!