English 中文(简体)
Java: Static Class?
原标题:

I have a class full of utility functions. Instantiating an instance of it makes no semantic sense, but I still want to call its methods. What is the best way to deal with this? Static class? Abstract?

最佳回答

Private constructor and static methods on a class marked as final.

问题回答

According to the great book "Effective Java":

Item 4: Enforce noninstantiability with a private constructor

- Attempting to enforce noninstantiability by making a class abstract does not work.

- A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

// Noninstantiable utility class
public class UtilityClass
{
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

Because the explicit constructor is private, it is inaccessible outside of the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees that the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive, as the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown above.

As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

Sounds like you have a utility class similar to java.lang.Math.
The approach there is final class with private constructor and static methods.

But beware of what this does for testability, I recommend reading this article
Static Methods are Death to Testability

Just to swim upstream, static members and classes do not participate in OO and are therefore evil. No, not evil, but seriously, I would recommend a regular class with a singleton pattern for access. This way if you need to override behavior in any cases down the road, it isn t a major retooling. OO is your friend :-)

My $.02

comment on the "private constructor" arguments: come on, developers are not that stupid; but they ARE lazy. creating an object then call static methods? not gonna happen.

don t spend too much time to make sure your class cannot be misused. have some faith for your colleagues. and there is always a way to misuse your class no matter how you protect it. the only thing that cannot be misused is a thing that is completely useless.

  • Final class and private constructor (good but not essential)
  • Public static methods

There s no point in declaring the class as static. Just declare its methods static and call them from the class name as normal, like Java s Math class.

Also, even though it isn t strictly necessary to make the constructor private, it is a good idea to do so. Marking the constructor private prevents other people from creating instances of your class, then calling static methods from those instances. (These calls work exactly the same in Java, they re just misleading and hurt the readability of your code.)

You can use @UtilityClass annotation from lombok https://projectlombok.org/features/experimental/UtilityClass





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签