【问题标题】:Is it better to have a single instance of a class, or simply have a bunch of static methods? [closed]拥有一个类的单个实例,还是仅仅拥有一堆静态方法更好? [关闭]
【发布时间】:2013-08-25 14:47:00
【问题描述】:

我一直在使用几种调用方法的方法。最近,我一直在使用一个类的静态实例,我相信这是它的正确术语(如果我错了,请纠正我)。哪个更好(甚至提出想法),为什么?

我的第一种方法是简单的旧静态方法。

static void exampleMethod1(){}
static void exampleMethod2(){}

第二种方式(有人说这是一种改进)。

public class ExampleClass{

    public static ExampleClass instance;

    public ExampleClass(){
    instance = this;
    }

    public static ExampleClass getInstance(){
        return instance;
    }

    void exampleMethod1(){
        //code
    }

    void exampleMethod2(){
        //code
    } 

    // To call the method I simply getInstance().exampleMethod1    

}

【问题讨论】:

  • 类的静态实例 不是正确的表达方式。这将描述引用某个实例的类的静态字段。您说的是在类类型上静态调用的方法。
  • 谢谢,我不确定这个词是什么。
  • "公共静态实例;"这直接或间接意味着什么。没有数据类型:O
  • 我们在对象实例化的时候在构造函数中赋值数据类型。
  • @Jaccob 您在该声明中缺少类型。 public static ??? instance; 应该是 public static ExampleClass instance;

标签: java class methods static


【解决方案1】:

您要查找的术语是singleton

单例上的静态方法和实例方法都是可以的方法,但是请注意,静态方法的方法不能实现接口,所以如果需要实现接口,请使用单例。

例如:

public enum HelloWorld implements Runnable {
    INSTANCE;

    @Override
    public void run() {
        System.out.println("Hello, world!");
    }
}

// ...
new Thread(HelloWorld.INSTANCE).start();

如果您的 hello-world 代码在静态方法中,则无法直接实现 Runnable 接口。

【讨论】:

  • 从未想过为此使用枚举,尽管我确实使用它们来实现 Comparator。酷:)
  • @StormeHawke 被称为“枚举单例模式”,在Effective Java 2nd ed 的第 3 项中有描述。那本书很值得一读,我认为每个 Java 程序员都应该读一读。 :-D
  • @StormeHawke Google I/O 2008 - Effective Java Reloaded 28:50 开始。
【解决方案2】:

如果所有方法都是静态的,并且您不需要初始化类或拥有类成员,那么只需创建一个静态实用程序类。

只有静态函数的静态类就可以了。

正如克里斯在我上面回答的那样,听起来您正在寻找一个单例,只有当您的类确实有非静态方面时才应该使用它,但您想限制它的实例数量。

public static class GeneralFunctions
{
    public static class ArrayFunctions
    {
         public static void OnArray{};
    }

    public static class PrintingFunctions
    {
        public static void PrintBuffer(byte[] buffer){};
        public static void PrintQword(ulong qword){};
    }
}

【讨论】:

  • 哈哈,我被告知拥有这样的静态实用程序类是“糟糕”的编程。
【解决方案3】:

您可以拥有一个只有静态方法的类,并且这些方法可以(如果需要)使用类中的静态字段来存储它们的持久数据。或者您可以使用“单例”类实例对实例方法和实例字段执行大致相同的操作。

一般来说,如果你有一个只包含没有状态的方法的类(例如,Math 类),你应该使这些方法成为静态的并且没有/允许实例。但是,如果方法必须具有某种共享状态,那么采用某种“单例”实现可能更明智。

【讨论】:

  • 拥有单身人士永远不会“更明智”,如果必须这样做,这是最后的手段。
  • 我认为无论如何让它成为一个非静态类可能是个好主意,即使没有状态,如果可以想象在未来的某个时候实现可以更改为需要状态的。然后,如果确实发生了这种情况,您就不必更改使用该类的所有代码。 Math 类将是一个示例,其中 可以想象永远需要该状态。但这真的取决于类代表什么以及其中的方法是做什么用的,当然我们不能用像ExampleClass这样的类来判断。
  • @TomF - 单例有几个优点。例如,您可以轻松地(并且可配置地)子类化一个单例,这对于全静态类来说充其量是尴尬的。 (但我确实同意,当有很多更好的选择时,单例往往会被用作第一选择。但这与静态方法无关。)
  • 我目前主要在 C++ 嵌入式系统中工作,所以相信我,我知道如何解决单身问题。尽管如此,除非你需要一个单例,否则你不应该使用单例,因为它“简单”或“可读”。
  • @TomF - 奇怪的是,我很少需要使用它们。
【解决方案4】:

要制作正确的单例,您必须将构造函数设为私有。静态最终声明确保实例将在第一次加载类时被初始化。这是在 Java 中创建单例的最简单方法,但请注意还有其他方法。

public class ExampleClass
{
    private final static ExampleClass instance = new ExampleClass();

    private ExampleClass()
    {
        // prevents instantiation
    }

    public static ExampleClass getInstance()
    {
        return instance;
    }

    void exampleMethod1()
    {
        //code
    }

    void exampleMethod2()
    {
        //code
    }     
}

获取类的实例:

ExampleClass exampleClass = ExampleClass.getInstance();
exampleClass.exampleMethod1();

【讨论】:

  • 最简单的方法是使用enum,正如克里斯在他的回答中所做的那样。多线程应用不用担心。
猜你喜欢
  • 2012-09-26
  • 2020-07-14
  • 1970-01-01
  • 2011-08-09
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
相关资源
最近更新 更多