今天听同事讨论说要尽量少用静态方法,但是有的人就以不用静态方法为准则,至于为什么不用,也说不出个所以然来。
今天这篇文章主要分享以下三个问题:
- 静态方法和实例方法区别是什么?
- 静态方法优缺点是什么?
- 哪些情况可以使用静态方法?
静态方法和实例放的区别是什么?
静态方法是可以与类实例无关地调用的方法。您只能在Static方法中访问静态属性和静态方法。
实例方法是只能使用对象引用调用的方法。实例方法可以访问实例属性和实例方法。
静态方法的优缺点是什么?
先说一说静态方法的优处:
- 不用生成类的实例就可以直接调用。
- static方法修饰的成员不再属于某个对象,而是属于它所在的类。只需要通过其类名就可以访问,不需要再消耗资源反复创建对象。
在类第一次加载的时候,static就已经在内存中了,直到程序结束后,该内存才会释放。如果不是static修饰的成员函数,在使用完之后就会立即被JVM回收。
创建静态方法听起来不错,而且很有利可图,因为在调用方法时不涉及冗长的步骤-声明引用变量,实例化对象和调用方法。无需执行这些步骤即可直接调用静态方法。但是也存在几点问题:
- static是反设计模式的
作为C系语言,static起源于C中的static,但是和C中的static语义却很不一样,根据《JLS 8.3.1.1》中的描述,static主要有以下语义:
If a field is declared
static
, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized.因此,常见的面向对象的技巧(比如继承、多态)无法很好地应用到static的方法上,除了函数重载(overload)以外,static方法无法很好地享受面向对象带来的便利性。static只是一种C中面向过程编程思想的延伸,在泛型成为高级语言标配的今天,我认为面向过程的编程方法不应该再被提倡了。
-
static不利于对类的精细化控制
在Java中,static的变量是和class绑定在一起的,也就是说在垃圾回收的过程中,除非class被回收掉,那么static的变量不会被垃圾回收。因此,在通常情况下,为了节约内存,降低GC压力,Java应用程序中不应该存在太多的static的属性(static final的编译期常量除外,当然也不能过大)。
-
静态方法不方便测试
个人认为,不容易测试是不使用静态方法的主要原因。PowerMock框架已经可以很好测试静态方法了。
哪些情况可以使用静态方法?
- 使用static方法来暴露类的构造工厂方法,比如String.valueOf(), LocalDateTime.now();
- 方法以后不会再修改和迭代。一些工具方法比如 Math.max(),单例,工厂模式等;
- 如果一个方法所有状态都可以封闭在栈内,变量不会逃逸到方法外(也就是说是无状态的),这样保证了方法的线程安全,所以可以使用static;
总结
静态方法之所以不推荐使用是因为其缺乏扩展性和可测试性,一旦使用静态方法,面向对象的继承多态特性也就不再适用。后续在往静态方法中添加逻辑就会出现很多 if else,因为你无法保证不同业务方的要求是一样的。如果你的方法不需要扩展,而且也可以很方便的写单元测试,使用静态方法并不是什么原罪。
转载请注明:XAMPP中文组官网 » 为什么静态方法不好? 静态方法的优缺点