Java 基础概念,一篇给你捋清楚

举报
yd_231768394 发表于 2026/10/19 21:29:50 2026/10/19
【摘要】 Java 基础概念,一篇给你捋清楚最近有朋友刚入行,问我 Java 入门到底要搞懂哪些概念。想了想,把我自己当年学 Java 时绕过弯路的地方整理一下,按顺序讲,尽量不整虚的。一、JDK、JRE、JVM 这三个东西这三个概念绕晕过不少人,其实一句话就能说明白。JVM 是 Java 虚拟机,负责执行编译后的字节码文件,也就是那个 .class 文件。我们常说的“一次编写,到处运行”,靠的就是它...

Java 基础概念,一篇给你捋清楚

最近有朋友刚入行,问我 Java 入门到底要搞懂哪些概念。想了想,把我自己当年学 Java 时绕过弯路的地方整理一下,按顺序讲,尽量不整虚的。

一、JDK、JRE、JVM 这三个东西

这三个概念绕晕过不少人,其实一句话就能说明白。

JVM 是 Java 虚拟机,负责执行编译后的字节码文件,也就是那个 .class 文件。我们常说的“一次编写,到处运行”,靠的就是它——不同平台有不同的 JVM 实现,但字节码是同一份。

JRE 是 Java 运行环境,比 JVM 大一圈,等于 JVM 加上运行程序必需的一些核心类库。你的程序只是要跑起来,装个 JRE 就够了。

JDK 是开发工具包,最大,等于 JRE 再加上一堆开发工具,javac、javadoc、jstack 这些都在里面。要写代码,装 JDK。

所以包含关系是 JDK > JRE > JVM,记住这个顺序基本就不会搞混。

二、基本数据类型和引用类型

Java 的数据类型分两大类,八种基本类型加引用类型。

基本类型是 byte、short、int、long、float、double、char、boolean,直接存值,存在栈上(严格说是存在栈帧的局部变量表里)。int 占 4 个字节,long 占 8 个,这个在算内存的时候用得上。

引用类型就多了,类、接口、数组都是。变量里存的不是对象本身,而是对象在堆里的地址,所以叫“引用”。这也是新手最容易懵的地方——两个变量用 == 比较,比的是地址不是内容,要比内容得用 equals:

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b);      // false,地址不同
System.out.println(a.equals(b)); // true,内容相同

顺带说一句 String,它虽然是个类,但因为用得太频繁,JVM 对它做了不少特殊处理,比如字符串常量池。这也是为什么面试总爱问 String 为什么设计成不可变的。

三、面向对象的三大特性

封装、继承、多态,这三个词背了这么多年,其实核心就一层意思:怎么把代码组织得更好维护。

封装就是把数据和操作数据的方法包在类里,内部实现细节藏起来,外面只暴露必要的方法。字段一般设成 private,通过 getter/setter 访问。有人觉得写 getter/setter 很啰嗦,但当几十处代码都直接读你的字段时,你就知道封装的价值了。

继承用 extends,子类拿到父类的字段和方法,可以复用也可以重写。Java 是单继承,一个类只能有一个直接父类,但可以实现多个接口。

多态是三个里面最精髓的。同一个方法调用,跑的时候执行的是哪个版本,取决于对象实际是什么类型:

Animal animal = new Dog();
animal.makeSound(); // 输出狗叫,而不是 Animal 里的默认实现

这就是动态绑定。写框架代码的时候特别依赖这个特性,面向接口编程,底下的实现随便换。

四、接口和抽象类

这两个东西长得像,用途不一样。

抽象类是“是什么”的关系,抽取的是一类事物的公共部分,可以带普通方法和字段。接口是“能做什么”的关系,定义的是一组行为契约,Java 8 之后接口里也能有 default 方法了。

选择上不用太纠结:要复用代码、有明显的父子层级,用抽象类;只关心能力、不关心是谁来实现,用接口。实际项目里接口用得多,因为解耦。

五、集合框架

平时写代码打交道最多的就是 java.util 包下这一堆。

List 是有序可重复,常用 ArrayList 和 LinkedList。绝大多数场景用 ArrayList 就行,底层是数组,随机访问快;LinkedList 是链表,理论上插删快,但实际因为它缓存不友好,多数时候反而不如 ArrayList。

Set 是不可重复,常用 HashSet,底层就是个 HashMap,add 的时候靠 hashCode 和 equals 判断重复。

Map 是键值对,HashMap 是绝对主力。它底层是数组加链表,JDK 8 之后链表长度超过 8 且数组长度达到 64 会转成红黑树,防止哈希冲突严重时查询退化成 O(n)。默认容量 16,负载因子 0.75,扩容翻倍。这些参数面试常问,但更重要的是理解为什么——扩容是有代价的,预估好初始容量能省不少事。

线程安全的场景别用老的 Hashtable,用 ConcurrentHashMap。

六、异常处理

异常分两大类:受检异常和非受检异常。受检异常比如 IOException,编译器强制你处理,要么 try-catch 要么往外抛。非受检异常就是 RuntimeException 及其子类,空指针、数组越界这些,编译器不管你。

实践上有几条朴素的经验。一是别捕获了异常什么都不干,空 catch 块是事故排查时的噩梦。二是别拿异常做流程控制,比如用 NumberFormatException 判断字符串是不是数字,能用正则就别这么写。三是自定义异常别滥用,业务代码里定义个统一的业务异常基类,够用了。

try {
    doSomething();
} catch (IOException e) {
    log.error("处理失败, 参数: {}", param, e); // 异常对象要传进去,堆栈别丢
    throw new BizException("处理失败", e);
}

七、泛型

泛型解决的是类型安全的问题。没有泛型的年代,从集合里取元素都得强转,类型错了要到运行时才炸。有了泛型,这类错误在编译期就能拦住。

List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0); // 不用强转

要理解的一点是 Java 的泛型是编译期的,运行时会擦除,泛型信息不在字节码里保留(部分场景例外)。这也是为什么 List<String> 和 List<Integer> 在运行时是同一个 Class,以及为什么不能写 new T() 这种代码。

八、最后

这些概念看着基础,但底层的细节要想全吃透,得在项目里踩过坑才有体会。刚入门不用追求一次全懂,先把封装继承多态和集合这两块用熟,其他的用着用着自然就通了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。