2103 字
11 分钟
Java 与 Go 语言对比笔记

1. 概述#

Java 和 Go 都是静态强类型、支持垃圾回收的编程语言,广泛应用于后端开发和分布式系统。

两者最大的区别在于设计理念:

  • Java:强调面向对象、平台无关性、成熟的运行时和丰富的企业级生态。
  • Go:强调简洁性、并发能力、工程效率和部署便利性。
对比维度JavaGo
类型系统静态强类型静态强类型
编程范式面向对象为主,支持函数式多范式,强调组合
面向对象Class、继承、接口Struct、Method、Interface
内存管理GCGC
并发模型Thread、JUCGoroutine、Channel
泛型支持支持(Go 1.18+)
错误处理Exception显式返回 error
编译结果JVM 字节码原生机器码
运行环境通常需要 JVM通常不需要独立运行时安装
部署方式JAR、容器等通常编译为独立二进制文件

2. 编程范式与面向对象#

2.1 Java:传统面向对象#

Java 以 Class 为核心组织程序。

主要特征:

  • 封装(Encapsulation)
  • 继承(Inheritance)
  • 多态(Polymorphism)
  • 抽象(Abstraction)

示例:

class Animal {
public void speak() {
System.out.println("Animal");
}
}
class Dog extends Animal {
@Override
public void speak() {
System.out.println("Dog");
}
}

Java 通过类、继承和接口组织代码,适合构建复杂的业务模型。

2.2 Go:组合式设计#

Go 没有传统的 Class 和继承体系,主要使用:

  • Struct:定义数据结构
  • Method:定义行为
  • Interface:定义行为约束
  • Composition:通过组合复用功能

Struct#

type Node struct {
key int
val int
}

Struct 可以理解为承载数据的结构体,类似 Java 中对象的字段部分。

Method#

func (n *Node) Print() {
fmt.Println(n.key)
}

(n *Node) 是 Receiver(接收者),表示该方法关联到 Node 类型。

Interface#

type Animal interface {
Speak()
}
type Dog struct{}
func (d Dog) Speak() {
fmt.Println("Dog")
}

Go 的接口采用隐式实现:

只要一个类型实现了接口要求的所有方法,就自动满足该接口,不需要显式声明 implements。

Composition#

Go 使用组合代替传统继承。

type Animal struct{}
func (a Animal) Eat() {
fmt.Println("eating")
}
type Dog struct {
Animal
}

Dog 嵌入 Animal 后,可以直接调用其方法。

2.3 面向对象机制对照#

JavaGo
ClassStruct
成员变量Struct 字段
成员方法Method
thisReceiver
构造函数通常使用 NewXxx 函数
extends组合、嵌入
implements隐式接口实现
多态Interface

注意:Struct 并不完全等同于 Class,Go 的方法也可以定义在符合条件的非结构体类型上。


3. 内存管理#

两门语言都具有自动垃圾回收机制。

3.1 Java#

Java 运行在 JVM 上,由 JVM 管理对象内存。

主要涉及:

  • 堆(Heap)
  • 虚拟机栈(JVM Stack)
  • 方法区(逻辑概念,具体实现随 JVM 版本变化)
  • 垃圾回收器(GC)

对象通常分配在堆上,GC 根据对象的可达性判断是否可以回收。

3.2 Go#

Go 使用自己的 Runtime 管理内存。

主要涉及:

  • Goroutine Stack
  • Heap
  • Garbage Collector
  • 内存分配器

Go 的 GC 主要采用并发标记清除机制,并通过 Runtime 管理 Goroutine、调度和内存分配。

3.3 对比#

对比JavaGo
内存分配JVM 管理Go Runtime 管理
垃圾回收JVM GCGo GC
手动释放对象通常不需要不需要
内存管理机制JVM 负责Runtime 负责

两者都不意味着完全不需要考虑内存管理,开发者仍然需要关注对象生命周期、内存占用和资源释放。

注意:文件、Socket 等外部资源不能只依赖 GC,应主动关闭。


4. 并发模型#

并发是 Go 的重要设计特点之一。

4.1 Java:Thread + JUC#

Java 主要通过线程实现并发。

常见机制:

  • Thread:线程
  • Runnable / Callable:任务抽象
  • ExecutorService:线程池
  • synchronized:内置锁
  • ReentrantLock:可重入锁
  • BlockingQueue:阻塞队列
  • Atomic:原子操作

示例:

ExecutorService pool =
Executors.newFixedThreadPool(4);
pool.submit(() -> {
System.out.println("running");
});
pool.shutdown();

Java 还提供虚拟线程(Virtual Threads,Java 21 正式引入),适合大量阻塞式任务场景。

4.2 Go:Goroutine + Channel#

Go 使用 Goroutine 作为轻量级并发执行单元。

启动 Goroutine:

go func() {
fmt.Println("running")
}()

只需要一个 go 关键字,就可以启动一个 Goroutine。

Go Runtime 负责调度 Goroutine,使大量 Goroutine 能够复用相对较少的操作系统线程。

4.3 Channel#

Channel 用于 Goroutine 之间传递数据。

func main() {
ch := make(chan int)
go func() {
ch <- 100
}()
value := <-ch
fmt.Println(value)
}

通信过程:

Goroutine A
|
| 发送数据
v
Channel
|
| 接收数据
v
Goroutine B

Go 的并发设计理念:

Do not communicate by sharing memory; instead, share memory by communicating.

不要通过共享内存来通信,而应该通过通信来共享内存。

不过 Go 也支持传统的共享内存同步方式,例如:

  • sync.Mutex
  • sync.RWMutex
  • sync.WaitGroup
  • sync.Once
  • sync/atomic

4.4 并发模型对比#

对比JavaGo
并发执行单元Thread / Virtual ThreadGoroutine
调度OS / JVM 相关机制Go Runtime
通信BlockingQueue 等Channel
互斥锁synchronized / LockMutex
等待任务CountDownLatch 等WaitGroup
并发控制ExecutorService 等Channel、Context、Semaphore 等

注意:Go 并不是所有并发场景都比 Java 快,两者性能需要结合具体任务评估。


5. 错误处理#

5.1 Java:异常机制#

Java 使用 Exception 处理异常。

try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}

主要分类:

  • Checked Exception:受检异常
  • Unchecked Exception:非受检异常
  • Error:严重错误

5.2 Go:显式返回 error#

Go 通常将错误作为函数返回值。

func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}

调用:

result, err := divide(10, 0)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)

Go 还有 panic 和 recover,但它们不是 Java Exception 的直接对应物。

5.3 对比#

JavaGo
try通常直接调用
catchif err != nil
throwreturn err
finallydefer
Exceptionerror
特殊异常控制panic / recover

Go 更强调错误显式传递,调用者需要明确处理错误。


6. 编译与运行机制#

6.1 Java:字节码 + JVM#

Java Source Code
|
v
javac
|
v
Java Bytecode
|
v
JVM
|
v
Operating System

特点:

  • 编译成平台无关的字节码。
  • 通过 JVM 执行。
  • JVM 可以使用 JIT 即时编译优化热点代码。
  • 通常需要 JVM 运行环境。

6.2 Go:编译为原生机器码#

Go Source Code
|
v
Go Compiler
|
v
Native Machine Code
|
v
Operating System

特点:

  • 通常直接编译为目标平台机器码。
  • 通常可以独立运行。
  • 编译时可以指定目标操作系统和架构。
  • 不需要像 Java 那样单独安装 JVM。

示例:

Terminal window
go build -o app main.go
./app

交叉编译:

Terminal window
GOOS=linux GOARCH=amd64 go build

7. 生态与典型应用#

7.1 Java 生态#

Java 具有成熟的企业级生态。

技术主要用途
Spring Boot后端应用开发
Spring Cloud微服务体系
MyBatis数据库持久化
Netty网络通信
Kafka消息系统
DubboRPC 框架
Maven / Gradle构建与依赖管理

典型场景:

  • 电商系统
  • 金融系统
  • 企业管理系统
  • 复杂业务后台
  • 大型微服务应用

7.2 Go 生态#

Go 在云原生和基础设施领域应用广泛。

项目主要用途
Docker容器技术
Kubernetes容器编排
Prometheus监控系统
etcd分布式键值存储
CaddyWeb 服务器
Hugo静态网站生成器
Traefik反向代理与流量管理

典型场景:

  • 云原生基础设施
  • 网络服务
  • 微服务
  • CLI 工具
  • DevOps 工具
  • 高并发服务

8. 总结:Java 与 Go 的设计取舍#

维度JavaGo
核心优势面向对象体系、JVM、成熟生态简洁、并发、部署便利
代码组织类、接口、继承Struct、Interface、组合
并发Thread、JUC、Virtual ThreadGoroutine、Channel
运行机制JVMGo Runtime
部署JVM 环境或容器独立二进制文件或容器
生态方向企业级业务开发云原生、基础设施、网络服务

一句话总结#

Java:通过成熟的面向对象体系和 JVM 生态,构建复杂的企业级软件。

Go:通过简洁的语言设计、轻量级并发和独立部署能力,构建高效的服务与基础设施。

两者并不是谁取代谁,而是设计取舍不同,适合不同的工程场景。


9. 学习建议#

如果已经掌握 Java 基础,再学习 Go,可以重点关注两门语言设计差异最大的地方:

  1. Struct、Method、Interface:理解 Go 如何组织代码。
  2. Pointer:理解 Go 的指针和引用传递。
  3. Slice、Map:掌握 Go 的常用数据结构。
  4. Error、Defer:掌握 Go 的错误处理和资源管理。
  5. Goroutine、Channel:掌握 Go 并发模型。
  6. Context:理解 Go 服务中的超时、取消和请求上下文传播。
  7. net/http:掌握 Go 网络编程。
Java 与 Go 语言对比笔记
https://blog.xqcherry.top/posts/learning/java-vs-go/
作者
xqcherry
发布于
2026-11-07
许可协议
CC BY-NC-SA 4.0