java Helper/Utility 类应该是抽象的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/309553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should Helper/Utility Classes be abstract?
提问by shsteimer
I commonly find myself extracting common behavior out of classes into helper/utility classes that contain nothing but a set of static methods. I've often wondered if I should be declaring these classes as abstract, since I can't really think of a valid reason to ever instantiate these?
我经常发现自己将类中的常见行为提取到只包含一组静态方法的帮助程序/实用程序类中。我经常想知道我是否应该将这些类声明为抽象类,因为我真的想不出实例化这些类的正当理由?
What would the Pros and Cons be to declaring such a class as abstract.
将这样的类声明为抽象类的利弊是什么。
public [abstract] class Utilities{
public static String getSomeData(){
return "someData";
}
public static void doSomethingToObject(Object arg0){
}
}
回答by Outlaw Programmer
You could just declare a private constructor that does nothing.
你可以声明一个什么都不做的私有构造函数。
The problem with declaring the class "abstract" is that the abstract keyword usually means that class is intended to be subclassed and extended. That's definitely not what you want here.
将类声明为“抽象”的问题在于抽象关键字通常意味着该类旨在被子类化和扩展。这绝对不是你想要的。
回答by Jon Skeet
Don't bother making them abstract, but include a private parameterless constructor to prevent them from ever being instantiated.
不要费心使它们抽象,而是包含一个私有的无参数构造函数以防止它们被实例化。
Point of comparison for those interested: in C# you would declare the class to be static, making it abstract andsealed (Java's final) in the compiled form, and without any instance constructor at all. That also makes it a compile-time error to declare a parameter, variable, array etc of that type. Handy.
感兴趣的人的比较点:在 C# 中,您可以将类声明为静态,使其在编译形式中抽象和密封(Java 的最终),并且根本没有任何实例构造函数。这也使得声明该类型的参数、变量、数组等成为编译时错误。便利。
回答by user38051
I don't declare utility classes abstract, I declare them final and make the constructor private. That way they can't be subclassed and they can't be instantiated.
我没有将实用程序类声明为抽象的,而是将它们声明为 final 并将构造函数设为私有。这样它们就不能被子类化,也不能被实例化。
public final class Utility
{
private Utility(){}
public static void doSomethingUseful()
{
...
}
}
回答by les2
I would add more step beyond the private constructor:
我会在私有构造函数之外添加更多步骤:
public class Foo {
// non-instantiable class
private Foo() { throw new AssertionError(); }
}
Throwing the AssertionErrorprevents methods in the same class from instantiating the class (well, they can try). This isn't normally a problem but in a team environment you never know what someone will do.
抛出AssertionError防止同一类中的方法实例化该类(好吧,他们可以尝试)。这通常不是问题,但在团队环境中,您永远不知道有人会做什么。
As regards the "abstract" keyword, I have noticed utilities classes subclassed in numerous instances:
关于“抽象”关键字,我注意到实用程序类在许多实例中都有子类:
public class CoreUtils { ... }
public class WebUtils extends CoreUtils { ... }
public class Foo { ... WebUtils.someMethodInCoreUtils() ... }
I believe this is done so that people don't have to remember which utility class to include. Are there any downsides to this? Is this an anti-pattern?
我相信这样做是为了让人们不必记住要包含哪个实用程序类。这有什么缺点吗?这是一种反模式吗?
Regards, LES
问候, LES
回答by Paul Sonier
By declaring them as abstract, you are in effect indicating to other coders that you intended for these classes to be derived from. Really, you're right, that there's not much difference, but the semantics here are really more about the interpretation of other people who look at your code.
通过将它们声明为抽象类,您实际上是在向其他编码人员表明您打算从中派生这些类。确实,您是对的,没有太大区别,但是这里的语义实际上更多是关于其他人查看您的代码的解释。
回答by Johannes Schaub - litb
As others stated, make a private parameter-less constructor. No-one can create an instance of it, apart from the class itself.
正如其他人所说,制作一个私有的无参数构造函数。除了类本身,没有人可以创建它的实例。
As others have shown how it is done with other languages, here comes how you do it in the next C++ version, how to make a class non-instantiable:
正如其他人已经展示了它是如何用其他语言完成的,这里是你在下一个 C++ 版本中如何做到的,如何使类不可实例化:
struct Utility {
static void doSomething() { /* ... */ }
Utility() = delete;
};
回答by Stefan Endrullis
I think it's better to declare utility classes final with a private no-args constructor. Moreover all members of this class should be static.
我认为最好使用私有的无参数构造函数将实用程序类声明为 final。此外,该类的所有成员都应该是静态的。
An easy way to do all this in one statement is to use the @UtilityClassannotation of Lombok:
在一个语句中完成所有这些操作的一种简单方法是使用@UtilityClassLombok的注释:
@UtilityClass
public class Utilities{
public String getSomeData() {
return "someData";
}
public void doSomethingToObject(Object arg0) {
}
}
If you use the @UtilityClassannotation you can skip the static keywords as in the example above since Lombok adds them automatically during compilation.
如果使用@UtilityClass注释,则可以跳过上面示例中的静态关键字,因为 Lombok 在编译期间会自动添加它们。
回答by Charles Bretana
No, but if your language supports it, there's a strong argument to be made that in most cases they should (can) be declared as 'static'... Static tells the compiler that they cannot be instantiated, and that all methods in them must be static.
不,但是如果您的语言支持它,则有一个强有力的论据可以证明在大多数情况下它们应该(可以)声明为“静态”......静态告诉编译器它们不能被实例化,并且它们中的所有方法必须是静态的。
Abstract is for classes that DO have instance-based implementation details, which WILL be used by instances of derived classes...
Abstract 用于具有基于实例的实现细节的类,这些细节将被派生类的实例使用......
回答by Bill K
Might I offer some constructive advice?
我可以提供一些建设性的建议吗?
If you are doing a lot of this, there are two problems you will run into.
如果你经常这样做,你会遇到两个问题。
First of all, a static method that takes a parameter should often be a part of the object that is that parameter. I realize this doesn't help for objects like String, but if it takes objects you've defined, you could almost certainly improve the object by including your helper as a method of that object.
首先,采用参数的静态方法通常应该是作为该参数的对象的一部分。我意识到这对像 String 这样的对象没有帮助,但如果它需要你定义的对象,你几乎肯定可以通过将你的助手作为该对象的方法来改进该对象。
If it takes all native values, you probably could define an object that it's a method of. See if you can find any grouping of those native values and group them as an object. If you just try that, you'll find a lot of other uses for that little mini-object, and before you know it it will be amazingly useful.
如果它采用所有本机值,您可能可以定义一个对象作为其方法。看看您是否可以找到这些原生值的任何分组并将它们分组为一个对象。如果你只是尝试一下,你会发现这个小物体还有很多其他用途,在你知道它之前它会非常有用。
Another thing, if you have a utility class with a bunch of semi-related static methods and static variables, you almost always want it to be a singleton. I found this out by trial and error, but when you find out you need more than 1 (eventually you will), it's MUCH easier to make a singleton into a multipleton(?) then to try to change a static class into a multipleton(okay, so I'm making words up now).
另一件事,如果您有一个包含一堆半相关静态方法和静态变量的实用程序类,您几乎总是希望它是一个单例。我通过反复试验发现了这一点,但是当你发现你需要 1 个以上(最终你会)时,将单例变成多例(?)然后尝试将静态类更改为多例(好的,所以我现在正在编造的话)。
Good luck. This stuff was mostly trial and error for me--figured it out like 5 years ago though, and I've never found an instance where I regretted not having static class/methods.
祝你好运。这些东西对我来说主要是反复试验——尽管 5 年前就想通了,但我从来没有发现过一个让我后悔没有静态类/方法的实例。
回答by matt_dev
Helper / Utility methods are just fine. Don't worry about adding them to a library inside your application or Framework. Most frameworks that I have seen use them in many varieties.
Helper / Utility 方法就好了。不要担心将它们添加到应用程序或框架内的库中。我见过的大多数框架都以多种方式使用它们。
That being said, if you want to get really crafty about them you should look into extension methodsin C# 3.0. Using extension method will make your Utilities a little more of a "holistic" part of your framework which it seems like what you're trying to do by considering to make them abstract. Not to mention extension method are a lot of fun to write!
话虽如此,如果您想真正了解它们,您应该研究C# 3.0 中的扩展方法。使用扩展方法将使您的实用程序更像是框架的“整体”部分,这似乎是您通过考虑使它们抽象来尝试做的事情。更何况扩展方法写起来很有趣!

