Java 中,究竟如何使用静态变量?

2016-08-18 11:17:53 +08:00
 miaoxia

曾见过一个大牛的观点:

  1. 代码中的静态变量最好不要超过 10 个。
  2. 而且静态变量要去序列化,当找不到这个变量时再解冻。

他说的是否有道理?


现在有这样一个需求:

如果我把这个 thread pool 定义为 static ,会有什么坏处吗

6295 次点击
所在节点    Java
33 条回复
georgema1982
2016-08-19 02:17:14 +08:00
一般的原则是 static 和变量可接受的组合是 final static ,即用来定义常量;不要有任何 static 的方法。现代 java 编程里,如果出现非 final 的 static 申明,基本上都是不可接收的
miaoxia
2016-08-19 09:00:17 +08:00
@asj 感谢回复
你说的有道理,可能我的设计本身存在问题。
miaoxia
2016-08-19 09:02:36 +08:00
@SoloCompany
感谢您的再次回复
如果设计不变,我会使用注入的方式来代替 static
asj
2016-08-19 09:40:53 +08:00
@miaoxia 说设计什么的可能有点虚,最直接的原因是这样的代码非常难写 unit test 。尝试一下就会有感觉了。
miaoxia
2016-08-19 09:42:28 +08:00
@hinkal 感谢您的回复
您给出的设计给了我很大启示

还想和您探讨下 “'多个子类想共享一个父类的线程池'会造成高耦合” 的问题
您是指 多个子类 与 共同父类 之间的耦合吗
如果我在父类中将与 threadPool 相关的操作 写成模板
在子类中去重写实际处理业务的方法 对于子类而言 是否异步是透明的(或者尽量透明)
这样还会产生耦合的现象吗

可能我对耦合的定义仍然不是那么明晰 请指教
miaoxia
2016-08-19 09:45:42 +08:00
@georgema1982 感谢回复
您的观点我完全赞同
只是实际工作中我在极力避免的过程中会遇到问题

除本文所指问题外
例如 Utils 类中,大家的惯例是 private Constructor
public 方法全部 static
您觉得这样的情况如何避免?
miaoxia
2016-08-19 09:59:38 +08:00
@hinkal 再补充下
我的问题中提到"子类去 submit 一个 runnable"
如果修改我上面说的实现,做出以下的实现:
1. 父类中的 thread pool 相关操作对于每个子类都是相同的,是一个共同的模板。
2. 由于是操作相同,当父类的线程机制做调整时,其他全部子类同时受影响。(子类是并列的概念,只是业务有区分)

如果实现共享父类的 thread pool ,会让全部的并行子类都单向依赖这个 thread pool 。
会产生高耦合的危害吗?

换句话说,当这个被依赖的模块,对于依赖它的模块的处理是统一的。
这样的情况,会产生高耦合的危害吗?
shyling
2016-08-19 10:15:51 +08:00
那些说注入的仿佛自己没有间接用 static 。。。乖乖用 Executor 不就好咯。。。接口标准库都封装好了。
hinkal
2016-08-19 12:12:52 +08:00
@miaoxia 如果“父类中的 thread pool 相关操作对于每个子类都是相同的”,那么放父类中做成”模板“,并且把对父类 threadpool 的操作放在父类方法中,这样对于子类,弗雷德 thread pool 是透明的,这样就不会高耦合吧。如果让子类都直接访问父类 static 对象,不符合迪米特法则,就是高耦合。
hinkal
2016-08-19 12:19:13 +08:00
@miaoxia ”您是指 多个子类 与 共同父类 之间的耦合吗 “不是,我指的是多个子类之间的耦合。本来,子类和父类之间不存在高耦合的问题,因为继承的目的就是公有一些方法和属性,然而你把所有子类产生的对象提交到父类的一个线程集合里,强行让他们互相可以引用,这样就让子类之间耦合起来了。
jason19659
2016-08-19 15:07:13 +08:00
你也知道静态变量的特点了,在符合这个特点,或者是使用这个最方便的时候可以用
TakWolf
2016-08-20 00:32:00 +08:00
凡是单例模式的通常都应该用 static

基于回收池或者重用池模式的,回收池实例声明周期为逻辑声明周期一致,因此,如果你是对 app 的回收池,通常他也是单例静态的
georgema1982
2016-08-20 02:07:40 +08:00
@miaoxia 说明“大家”都还在用老式的设计模式,即用 java 本身的特性来管理一个类的生命周期。现代的设计模式是不要自己实现生命周期,把所有 java 类都写成 pojo 。这种 pojo 不应该有非 public 的 constructor ,不应该存在 static 的方法。你们公司里如果还在用这种老式的设计模式的话,我第一反应就是你们公司不做单元测试

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

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

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

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

© 2021 V2EX