一个类只有静态字段和方法是不好的做法?

我有一个包含静态成员variables和静态方法的类。 本质上,它是一个通用的实用类。

一个类只包含静态成员variables和静态方法是不好的做法?

不,我不这么认为。 让一个实际上并不依赖于特定实例的实例方法成为一个类是更糟的做法。 使它们静态地告诉用户它们是如何被使用的。 另外,这样可以避免不必要的实例化。

编辑:作为一个事后,一般来说,我认为它很好,以避免使用语言function“只是因为”,或者因为你认为这是“Java的方式去做”。 我记得我的第一份工作,我有一个充满静态工具方法的课程,其中一位高级程序员告诉我,我没有充分利用Java的面向对象的强大function,把我所有的方法都设置为“全局”。 6个月后她不在队伍中。

只要这个阶级没有内在的国家,实际上就是所谓的叶类(实用阶级属于这一类),换言之,它是独立于其他阶级的。 没事。

Math课是一个很好的例子。

听起来很合理。

注意:执行此操作的类通常具有私有的无参数构造函数,以便编程器在尝试创build静态类的实例时产生错误。

静态方法不用担心太多(除了testing)。

一般来说,静态成员是一个问题。 例如,如果您的应用程序是群集的呢? 启动时间怎么样 – 正在进行什么样的初始化? 对于这些问题和更多的考虑,请查看Gilad Bracha的这篇文章 。

这是完全合理的。 事实上,在C#中,您可以专门为此定义一个具有static关键字的类。

只是不要被它带走。 请注意,java.lang.Math类只是关于math函数。 例如,您可能还有一个StringUtilities类,其中包含常用string处理函数,这些函数不在标准API中。 但是,如果您的课程名为“实用工具”,则可能需要将其分解。

还要注意,Java专门介绍了静态导入:( http://en.wikipedia.org/wiki/Static_import

静态导入是Java编程语言中引入的一种function,即在类中定义的成员(字段和方法)为公共静态,以在Java代码中使用,而不指定定义该字段的类。 5.0版本中引入了该function。

该function提供了一种types安全机制,可以将常量包含到代码中,而无需引用最初定义该字段的类。 它也有助于不赞成创build一个常量接口的做法:一个只定义常量的接口,然后编写一个实现该接口的类,这被认为是接口的不当使用[1]。

该机制可以用来引用一个类的个别成员:

  import static java.lang.Math.PI; import static java.lang.Math.pow; 

或者一个类的所有静态成员:

  import static java.lang.Math.*; 

虽然我同意这个看起来像是一个合理的解决scheme(正如其他人已经说过的那样),但是从devise的angular度来看,你可能要考虑的一件事是,为什么你只有一个class级才是“实用”的目的。 这些泛函是否在整个系统中是真正的generics,还是与架构中某些特定的对象types有关?

只要你有这个想法,我认为你的解决scheme没有问题。

Java SDK中的Collections类只有静态成员。

所以,只要你有合适的理由,你就去了 – 这不是一个糟糕的devise

实用程序方法通常放在只有静态方法的类(如StringUtils 。全局常量也放在它们自己的类中,以便可以通过其余代码( public final static属性)导入它们。

这两个用法是相当普遍的,并有私人的默认构造函数,以防止它们被实例化。 声明类最终可以防止尝试覆盖静态方法的错误。

如果通过static member variables你不是指全局常量,你可能希望把访问这些variables的方法放在它们自己的类中。 在这种情况下,你能否详细说明这些variables在你的代码中的作用?

这通常是如何devise实用程序类,并没有什么错。 着名的例子包括oaclStringUtilsoacdDbUtilsoswbServletRequestUtils

根据面向对象devise的一个严格的解释,实用程序类是应该避免的。

问题是,如果你遵循一个严格的解释,那么你需要强制你的类进入一些sorting对象,以完成很多事情。

即使是Javadevise者也会创build实用类(想到java.lang.Math)

您的select是:

 double distance = Math.sqrt(x*x + y*y); //using static utility class 

VS:

 RootCalculator mySquareRooter = new SquareRootCalculator(); mySquareRooter.setValueToRoot(x*x + y*y); double distance; try{ distance = mySquareRooter.getRoot(); } catch InvalidParameterException ......yadda yadda yadda. 

即使我们要避免冗长的方法,我们仍然可以结束:

 Mathemetician myMathD00d = new Mathemetician() double distance = myMathD00d.sqrt(...); 

在这种情况下,.sqrt()仍然是静态的,那么在创build对象的时候又会是什么呢?

答案是,创build工具类时,你的其他select是创build一些人工“工人”类没有或很less使用实例variables。

这个链接http://java.dzone.com/articles/why-static-bad-and-how-avoid似乎违背了这里的大部分答案。; 即使它不包含成员variables(即没有状态),静态类仍然是一个坏主意,因为它不能被模拟或扩展(子类),所以它正在破坏面向对象的一些原则

我不会担心包含静态方法的工具类。

但是,静态成员基本上是全局数据,应该避免。 如果它们被用于caching静态方法等的结果,那么它们可能是可以接受的,但如果它们被用作可能导致各种问题的“真实”数据,如隐藏的依赖性和难以build立testing的问题。