避免在java中实例化一个类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1326230/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:17:50  来源:igfitidea点击:

Avoid instantiating a class in java

javaclassinstantiation

提问by jai

Recently I've faced a question : How to avoid instantiating a Java class?

最近我遇到了一个问题:如何避免实例化 Java 类?

However, I answered by saying:

然而,我回答说:

  1. If you don't want to instantiate a class, use "abstract" modifier. Ex: javax.servlet.HttpServlet, is declared as abstract(though none of its methods are abstract) to avoid instantiation.

  2. Declare a no argument private constructor.

  1. 如果您不想实例化一个类,请使用“抽象”修饰符。例如:javax.servlet.HttpServlet,被声明为抽象的(尽管它的方法都不是抽象的)以避免实例化。

  2. 声明一个无参数的私有构造函数。

Now my question is a) are there any other ways? b) why does any one do not want to instantiate a class? - after searching in SO, I got to know from thisthat Util classes can be made not to instantiate. Any other places where we don't want to instantiate a class in OOP?

现在我的问题是 a) 还有其他方法吗?b) 为什么有人不想实例化一个类?-在SO搜索后,我从知道这个那个的Util类可以不进行实例化。我们不想在 OOP 中实例化类的任何其他地方?

采纳答案by cletus

Four reasons spring to mind:

四个原因浮现在脑海:

  1. To allow subclasses but not the parent to be instantiated;
  2. To disallow directinstantiation and instead provide a factory method to return and if necessary create instances;
  3. Because all the instances are predefined (eg suits in a deck of cards) although since Java 5, typesafe enums are recommended instead; and
  4. The class really isn't a class. It's just a holder for static constants and/or methods.
  1. 允许实例化子类而不是父类;
  2. 禁止直接实例化,而是提供一个工厂方法来返回,并在必要时创建实例;
  3. 因为所有实例都是预定义的(例如一副牌中的花色),尽管从 Java 5 开始,建议使用类型安全的枚举;和
  4. 班级真的不是班级。它只是静态常量和/或方法的持有者。

As an example of (2), you may want to create canonical objects. For example, RGB color combinations. You don't want to create more than one instance of any RGB combo so you do this:

作为 (2) 的示例,您可能想要创建规范对象。例如,RGB 颜色组合。您不想创建任何 RGB 组合的多个实例,因此您可以这样做:

public class MyColor {
  private final int red, green, blue;

  private MyColor(int red, int green, int blue) {
    this.red = red;
    this.green = green;
    this.blue = blue;
  }

  public static MyColor getInstance(int red, int green, int blue) {
    // if combo already exists, return it, otherwise create new instance
  }
}

Note:no no-arg constructor is required because another constructor is explicitly defined.

注意:不需要无参数构造函数,因为显式定义了另一个构造函数。

回答by jW.

I think the most common reason for not wanting to instantiate a class is when you are dealing with a static class, and therefore with its static methods. You don't want someone to try to instantiate that class. Likewise, when you are dealing with Factory classes or in some cases many singleton classes will hide their constructor as to not be instantiated in the normal way.

我认为不想实例化类的最常见原因是当您处理静态类时,因此处理其静态方法。您不希望有人尝试实例化该类。同样,当您处理工厂类或在某些情况下,许多单例类会隐藏它们的构造函数,以免以正常方式实例化。

回答by Zed

Sometimes you only want to avoid others instantiating your objects, in order to have full control over all existing instances. One example is the singleton pattern.

有时您只想避免其他人实例化您的对象,以便完全控制所有现有实例。一个例子是单例模式

回答by Stephen C

Another way to make a class non-instantiable would be to declare it as a private inner class, and then not provide any way to instantiate it in the surrounding class. But this is (IMO) pretty pointless.

使类不可实例化的另一种方法是将其声明为私有内部类,然后不提供任何方法在周围的类中实例化它。但这(IMO)毫无意义。

You want a class to be non-instantiable if it makes no sense to instantiate it. You generally do this if the class is really just a collection of (static) helper methods, or if the class is "incomplete". The incompleteness may be syntactically obvious (i.e. abstract methods), but there other kinds of incompleteness. For example, you might provide default default implementations for all methods, and require one or more of them to be overridden for the class to do something useful.

如果实例化它没有意义,您希望一个类是不可实例化的。如果该类实际上只是(静态)辅助方法的集合,或者该类“不完整”,则通常会执行此操作。不完备性可能在句法上很明显(即抽象方法),但还有其他类型的不完备性。例如,您可能为所有方法提供默认的默认实现,并要求覆盖其中的一个或多个,以便类做一些有用的事情。

Another reason to make a class non-instantiable (or at least, not directly instantiable) is if your application needs to control the instantiation. For example, the java.util.regex.Pattern class cannot be directly instantiated so that the JRE can (could) maintain a cache of pre-compiled regexes.

使类不可实例化(或至少不可直接实例化)的另一个原因是您的应用程序是否需要控制实例化。例如,java.util.regex.Pattern 类不能直接实例化,因此 JRE 可以(可以)维护预编译正则表达式的缓存。

回答by Kolibri

Not really an answer to your question but just a note:

不是你问题的真正答案,只是一个注释:

When you make a private no-arg constructor to prevent instantiation of your utility classes, you should have the constructor throw an exception (e.g. UnsupportedOperationException). This is because you can actually access private members (including constructors) through reflection. Note that if you do so, you should accompany it with a comment, because it is a bit counter-intuitive that you define a constructor to preventa class from being instantiated.

当你创建一个私有的无参数构造函数来阻止你的实用程序类的实例化时,你应该让构造函数抛出一个异常(例如 UnsupportedOperationException)。这是因为您实际上可以通过反射访问私有成员(包括构造函数)。请注意,如果你这样做,你应该附上注释,因为你定义一个构造函数来防止类被实例化有点违反直觉。

Making the utility class abstract is not a good idea because it makes the class look like it is intended to be extended, and furthermore you can extend the class and thereby instantiate it.

使实用程序类抽象并不是一个好主意,因为它使类看起来像是要扩展的,而且您可以扩展类并由此实例化它。