26
0
0

试手

2026-09-06
2026-09-27
试手
文章摘要

从 C 和 Python 转到 Java:一个初学者的三语言对比笔记

我先学了 C 语言,又用了一段时间 Python,现在开始学 Java(目标是后端开发)。这篇文章记录我对三门语言的对比理解——不是教科书式的罗列,而是"从一个语言切换到另一个语言时,真正会卡住你的那些点"。

一、先看最本质的区别:代码是怎么跑起来的

这是三门语言最根本的差异,理解了这一点,后面很多"为什么"都能自己推出来。

C:编译成机器码,直接执行

源代码(.c) → 编译器(gcc) → 机器码(.exe) → CPU 直接执行


C 代码编译后就是针对特定平台的机器码,Windows 上编译的程序拿去 Linux 跑不了。快,是真的快,但换个系统就得重新编译。

**Python:解释执行,边翻译边跑**

源代码(.py) → 解释器(CPython) → 逐行翻译成字节码并执行


不需要编译,写完直接 `python xxx.py` 就跑。代价是运行速度慢——同一行代码,Python 可能比 C 慢几十上百倍。

**Java:先编译成字节码,再由 JVM 执行**

源代码(.java) → 编译器(javac) → 字节码(.class) → JVM 解释/JIT 执行


Java 走了个中间路线:编译一次,生成"字节码",然后由 Java 虚拟机(JVM)来执行。只要有 JVM 的地方(Windows、Linux、macOS),同一个 .class 文件都能跑——这就是那句著名的口号:

> **一次编写,到处运行(Write Once, Run Anywhere)**

JVM 还有个 JIT(即时编译)机制:运行时把热点字节码再编译成机器码,所以 Java 比 Python 快,但一般还是比 C 慢一点。

| | C | Python | Java |
|---|---|---|---|
| 执行方式 | 编译成机器码 | 解释执行 | 编译成字节码 + JVM |
| 运行速度 | 最快 | 最慢 | 较快 |
| 跨平台 | ❌ 需重新编译 | ✅(需装解释器) | ✅(需装 JVM) |
| 典型用途 | 操作系统、嵌入式 | 脚本、AI、数据分析 | 企业后端、Android、大数据 |

## 二、类型系统:从"自由的 Python"回到"严格的 Java"

用惯 Python 的人第一次写 Java,最容易崩溃的就是这里。

**Python(动态类型)**:

```python
x = 10          # x 是 int
x = "hello"     # 没问题,x 现在是 str

变量本身没有类型,值才有类型。写起来飞快,但坑也在这——变量拼错、传错类型,运行时才炸。

C(静态类型):

int x = 10;
x = "hello";  // 编译报错

类型在编译期就定死,写错编译器直接骂你。

Java(静态类型 + 更严格):

int x = 10;
x = "hello";  // 编译报错

这一点上 Java 和 C 长得像。但 Java 比 C 严格的地方在于强类型:不同类型之间不会偷偷转换。C 里 if (指针) 能编译过,Java 直接不允许。可以说:

Java 的类型系统 = C 的静态检查 + 比 C 更严格的类型约束 + 一切皆对象(int 之外还有 Integer 包装类)

对学过 C 的人来说,接受 Java 的类型并不难;难的是反过来——用 Java 的思维要求自己去明确声明每个变量的类型,而不能再靠 Python 那种"反正运行时再说"的随性。

三、内存管理:从"自己扫雪"到"有保洁"

这是三门语言分工最鲜明的一块。

C Python Java
内存分配 malloc / free 手动 自动 new 分配,自动回收
回收方式 程序员自己 free 引用计数 + 垃圾回收 GC 垃圾回收
后果 忘 free → 内存泄漏;free 两次 → 崩溃 基本不用管 基本不用管

写 C 的时候,malloc 和 free 必须严格配对,漏一个就是内存泄漏,多一个就是程序崩溃——这门课《数据结构》里链表的销毁操作就是这个味。

Java 里你只管 new,不用(也不能)手动释放。JVM 的垃圾回收器(GC)会自动识别"没有被任何对象引用的内存"并回收。Python 也是自动的(引用计数为主),所以从 Python 过来的人对 GC 不会陌生;真正觉得"解放了"的,是从 C 过来的人。

当然,GC 不是免费的:它会带来停顿和内存开销,这也是为什么操作系统内核、实时系统这种场景至今还是 C/C++ 的天下。

四、语法对比:同一个例子写三遍

用"定义一个学生类,打印学生信息"来感受一下三门的画风。

C(面向过程,用结构体):

#include <stdio.h>
#include <string.h>

struct Student {
    char name[20];
    int score;
};

int main() {
    struct Student s;
    strcpy(s.name, "Tom");
    s.score = 90;
    printf("%s: %d\n", s.name, s.score);
    return 0;
}

Python(面向对象,但极其简洁):

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

s = Student("Tom", 90)
print(f"{s.name}: {s.score}")

Java(纯面向对象,一切代码都在类里):

public class Main {
    static class Student {
        String name;
        int score;

        Student(String name, int score) {
            this.name = name;
            this.score = score;
        }
    }

    public static void main(String[] args) {
        Student s = new Student("Tom", 90);
        System.out.println(s.name + ": " + s.score);
    }
}

几个第一眼就能注意到的差异:

  1. Java 的代码量明显多于 Python——没有缩进魔法,一切用 {} 包起来,每个语句以 ; 结尾(这点和 C 一样)。
  2. Java 强制面向对象:连 main 函数都必须挂在某个类里,不存在"类外面的代码"。C 没有类的概念,Python 类是可选的,Java 类是必需的。
  3. 声明对象要 new:Student s = new Student(...),左边声明类型,右边创建对象。这比 Python 的 s = Student(...) 啰嗦,但意思更明确。

五、那些从 C / Python 过来才会注意到的细节

1. Java 没有"游离"的函数,也没有头文件

C 的函数可以独立存在,靠 .h 文件做声明;Python 的函数也可以写在模块顶层。Java 里一切方法是类(或对象)的成员,组织代码的单位就是类。

2. 字符串:Java 的 String 是对象,且不可变

  • C:char 数组 + 一堆 <string.h> 函数,手动管理,容易越界
  • Python:str 不可变,天然安全
  • Java:String 是对象、不可变(和 Python 一样),拼接多了要改用 StringBuilder(性能考虑)

3. 数组:Java 会做边界检查

C 里数组越界不报错、直接写出玄学 bug;Java 数组越界会抛 ArrayIndexOutOfBoundsException,程序立刻告诉你死在哪。这是"安全"换"性能"的典型体现。

4. Java 的包(package)≈ Python 的模块(module)

Python 用 import numpy as np,Java 用 import java.util.List;。概念相通,但 Java 的包名有强制约定(域名倒序,如 com.example.demo),工程化味道更浓。

5. 异常处理:Java 强迫你表态

Python 的异常可以不处理(炸了就炸了),Java 的"受检异常"(checked exception)会强制你 try-catch 或在方法签名上声明 throws。写的时候嫌烦,维护别人的代码时会觉得真香。

六、总结:三门语言教会我的三种思维

语言 教会我的事
C 内存和指针的真实存在——数据是怎么躺在内存里的
Python 快速表达想法——关注问题本身而非语言细节
Java 工程化协作——类型安全、规范约束,让几十人的团队维护百万行代码不至于失控

如果只用一个比喻:C 是手动挡老款车,一切自己控制,性能拉满但容易熄火;Python 是自动挡家用车,好开省心,但极限操控差点;Java 是一辆规矩很多的公司车队用车——上下车流程繁琐,但胜在安全、可靠、谁来开都不容易出事故。

作为初学者,我对 Java 的感受是:门槛在于"规矩多",价值也在于"规矩多"。接下来我会继续记录 Java 学习路上的笔记,下一篇打算写 Java 集合框架(ArrayList / HashMap)和我已熟悉的 C 链表、Python list 的对比。


本文首发于我的博客,欢迎交流指正。


支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

试手
/archives/shi-shou
作者
簌胡思
发布于
2026-09-06
许可协议
CC BY-NC-SA 4.0