在 Java 中为什么不全部使用 static 方法?

2022-07-21 10:55:45 +08:00
 qiqiqi7001

为什么不能全部用 static

10487 次点击
所在节点    Java
103 条回复
guyuesh3
2022-07-21 15:50:09 +08:00
@qiqiqi7001

本质上要分析对象和 static 就是要深入 JVM 才能明白啊,因为是 JVM 帮你管理你的 class ,你的对象的啊。

语言语法的特性需要虚拟机帮助实现啊。

参考:jvm specification / java launguage specificatiion

https://docs.oracle.com/javase/specs/
aguesuka
2022-07-21 15:56:48 +08:00
因为 Java 里的 Object 相当于 FP 里面的 Context, Java 全用 static 相当于 FP 不用闭包
qiqiqi7001
2022-07-21 16:02:45 +08:00
@guyuesh3 我主要不是关注 static 这个关键字本身的原理,我看到“java 万物皆对象”感觉说的不太对,我觉得对象不是必须的,大部分用对象的地方都可以用 static 替换,所以我才问为什么不能全部用 static ,但我现在了解到 static 是和 oop 冲突的,这个可以说是一个不能全部 static 的一个原因。
qiqiqi7001
2022-07-21 16:08:37 +08:00
@guyuesh3 早期的,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建 c++,java,c# 这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。
我复制别人的一句话,这个就是我要找的答案。
luozic
2022-07-21 16:13:34 +08:00
benchmark 一下,什么时候运行得时候创建对象 和启动得时候就创建对象 性能一样了? 多 benchmark debug jvm ,少 yy 和虚空打靶。
lux182
2022-07-21 16:14:13 +08:00
这是一个好问题。
第一从设计理念上看,静态方法是不需要实例化对象就能调用。使用要分场景,要不就不规范,让人迷惑
第二从 jvm 类加载上看,静态方法是内存不节约的
qiqiqi7001
2022-07-21 16:32:00 +08:00
lancelock
2022-07-21 17:13:58 +08:00
你可以这样写啊,没人拦着
NeoZephyr
2022-07-21 17:37:46 +08:00
如果全部是单例,也不是不可以
nekoneko
2022-07-21 18:06:52 +08:00
java 面向对象里重要的一点是集成和实现, 全 static 就和这点相悖了
nekoneko
2022-07-21 18:07:05 +08:00
@nekoneko #70 继承和实现
cmdOptionKana
2022-07-21 18:24:01 +08:00
@qiqiqi7001

面向对象是 Java 被发明时的编程界的一个思潮,因此 Java 被设计为更容易采用面向对象的编程模式,Java 程序员也更喜欢采用面向对象方式。

但现在最新的思潮,也有认为面向对象不一定好,比如声名大噪的 Rust 和 Go 语言就不支持标准的(完整的) OOP ,照样得到很多关注和使用。

因此你说尽量多用 static 行不行,当然行,只是 Java 在设计上和生态上不便于采用这种方式。如果你问 Java 为什么不全部使用 static, 那很简单,Java 的设计者与使用者选择了 OOP ,在当时的历史背景下是一个很好的选择,而现在则是有历史包袱。

如果你问不采用 OOP 行不行,当然行,Emacs Lisp 和 Erlang 还活着呢,JavaScript 里也有大量代码不用 class 。
Suddoo
2022-07-21 18:24:47 +08:00
可以,Spring 不就是这么干的,所有东西放内存里,想用谁用谁,跟 import static 有什么本质上的区别吗?
ToBeHacker
2022-07-21 18:46:17 +08:00
成员方法不就是把 this 作为第一个参数的 static 方法么,这就是语法糖的差异吧
pkoukk
2022-07-21 18:50:24 +08:00
没怎么写过 java ,上学的时候听老师说不用的 static 函数也会被加载进内存里
是现在 jvm 升级了么,动态编译时会省略不用的 static 函数嘛
luozic
2022-07-21 19:26:55 +08:00
@qiqiqi7001 这个是触发了 jvm 得 hotspot 编译了,一般得大部分代码会连续跑 10w 次?
janus77
2022-07-21 19:32:52 +08:00
所以你反对的只是“面向对象”这个原则而已?那你别用 java 啊,编程有各自的流派,你强行要求一个本来就是为面向对象而设计的语言去写成面向过程的东西,图什么呢?
stephenyin
2022-07-21 20:02:04 +08:00
讨论的越长的帖子,讨论的内容越没什么技术高度。😂
undeflife
2022-07-21 21:51:26 +08:00
内存分配上是有区别的,static method 和其他类元信息都保存在 permanent generation ,这个是固定尺寸的,具体细节参考 gc turning 手册,jdk 8 之后移除了,改成了使用非 Java heap 内存且会自增的 Metaspace ,但细节取决于 jvm 实现,另外印象中 static method 是不会有 jit 优化的,我怀疑优化后的普通 method 会比未优化的 static method 快。
ychost
2022-07-21 21:57:27 +08:00
起始是语言的设计问题,像 Node 就不用关心是否 static ,反正 function 一把梭,Java 更多的是为大工程服务的,比如实现 SPI 等能力都是靠多态来解决的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/867705

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX