书写方面: Go 语句在语句末尾并不使用;分号结束。Java 必须以 ; 结尾。
GC 方面: Go与Java都有垃圾收集器(GC),以防止内存泄漏。Go 语言的 GC 工具的表现很优秀,它的处理时间在 1.8版本中不到 1ms 即可完成。虽然随着 G1 和 ZGC 的出现缩短了与 Go 的差距,但显然 Go 更擅长管理内存。它不包含引用链接,而是包含指针,而且 Go 的垃圾收集器经过大量优化以防止 STW。整体上 Go 的垃圾收集方法更精细。且在 Go 语言中,其 GC 的设置参数并不多,有一个唯一的 GC 变量用来设置初始时垃圾回收目标的百分比。在 Java 中,有 4 个不同的垃圾收集器,每一个都要有大量的设置工作。
跨平台方面: Java 和 Go 都被视为跨平台语言,但是 Java 需要 JVM 来解析编译后的代码,而 Go 可以简单地将代码编译为给定平台的二进制文件,虽然它不是跨平台性语言,但它在编码器层面依然可以实现一套代码编译出不同平台的执行文件,可以直接在各个平台上运行。Go 比 Java 依赖度更低,因为 Go 每次为一个平台编译代码时都要创建一个二进制文件。从测试和 DevOps 角度来看,分别编译不同平台的二进制文件非常的费时,有时候使用 Go 组件时,跨平台的 Go 编译在一些情况下并不起作用。但 Java 则可以在有 JVM 的任何地方使用一个 Jar。
内存占用方面: Go 占用内存很小,而且并不需要安装和管理虚拟机的关联依赖,以及复杂的注意事项。 Java的反射功能很强大,而Go的反射更偏复杂。Java是一种纯面向对象语言,所有内容都被视为对象。
反射原理方面: 在 Java 使用反射,需要为对象创建一个类,并从此类中获取所需要的信息。然后就可以访问构造函数、方法和属性,然后去调用和设置它们;在 Go 语言中,则没有类的概念,它的结构中仅包含已声明的字段。因此,我们需要它的反射包来提供相关信息。
修饰符: Java 具有 private、protected 以及 public 这 3 个修饰符,用来对数据、方法和对象提供不同范围的存取。Go 语言中,有着和 Java 类似的语法 exported/unexported 修饰符。在 Go 中如果没有修饰符,以大写字母开头的所有内容都能够导出,并且在其它软件包中可见。unexported 以小写变量或函数仅在当前包中可见。
面向对象: Go 语言并不是一种面向对象语言,它没有像 Java 中的继承,没有通过继承这一特性实现系统的多态性。Go 语言没有对象,只有结构体。但可以通过提供接口实现一些面向对象的模式。同样道理,可以将结构彼此嵌入,但是嵌入式结构无法访问宿主结构的数据和方法。Go中使用组合,而不使用继承来组合一些所需的行为和数据。
语言类型:Go 是一种命令式语言,而 Java 则是一种声明式语言。
依赖注入: Go 中没有依赖式注入的功能,在 Go 中必须将所有内容明确的包装在一块。因此,在 Go 中编程末尽量少用一些魔术方法,一切都是可见的。
开发导向:Go 程序员要了解 Go 代码如何使用内存、文件系统以及其它关联资源的全部机制。Java 需要开发人员更多的关注自定义开发的业务逻辑部分,诸如如何创建、过滤、更改和存储数据。从系统基础架构和数据库管理系统而言,所有这些都是通过配置和通过Spring Boot等通用框架来完成。人们总是矛盾心理,我们对基础架构的部分感到枯燥乏味,因此这部分功能交给框架。这会给我们带来方便,但对于程序员来说,控制权在框架,也限制人们对整个流程优化的能力。
变量定义及顺序:在 Java 中定义变量为类型 + 变量名,而在 Go 中是变量名 + 类型。
并发性: Go 作为一种为现代多核计算机设计的语言,简单优雅的并发,并且具有强大的并发模型,其设计基于 两级线程模型改进的 GMP 模型,这样能大大减少并发切换线程的性能开销,而且这些模型统一封装到语言级别的调度层,只需通过关键字 go 就可以开启协成,提高了易用性。Java 语言上没有协程的概念,Java 的线程模型依然用的 内核级线程模型,多线程开发依然需要复杂的实现,而且实现方式有很多种,你需要了解每种实现方式的优缺点才能写出高性能的代码,除了这些还需要了解各种锁,来保障你写的线程是安全的。
异常: Go 不使用异常,而是使用错误 (error) 来表示诸如文件结束之类的事件,并使用运行时恐慌 (panic) 来表示运行时错误,例如尝试索引数组越界。
泛型: Java 的泛型通过类型擦除来实现,使一些代码更清晰,但是不支持泛型数组,并且具有上限和下限的类型通配符等,这让编码变得很复杂。而 Go 泛型没有 Java 的复杂,它有一些内置的泛型数据类型,比如:切片和 map 等,使用起来比较方便清晰易懂。
安全性: Java 语言本身并不能保护你免受漏洞的侵害,但它的某些功能可以使您免受常见的安全漏洞的侵害。比如没有指针能避免一些未经授权的访问内存操作。其次 Java 有不同权限的访问修饰符,为每个应用程序创建不同级别的访问权限。从 Go 1.13 开始,go 命令默认使用 Go 模块镜像和 Go 校验和数据库下载和验证模块,语言层面内置安全策略。