2017-10-08 57 views
-1

//问题:将一个类的实例限制为一个。如何限制类实例化为一个?

class Runtime{ 
    private static Runtime r; 
    private Runtime(){ 
    System.out.println("In Runtime class."); 
    } 
    static{ 
    r=new Runtime(); 
    } 
    static Runtime getRuntime(){ 
    Runtime r=new Runtime(); 
    return r; 
    } 
} 

class TestRuntime{ 
    public static void main(String[] args) { 
     Runtime r1; 
     r1=Runtime.getRuntime(); 
    } 
} 

我想了解一下这个代码实际上做,以及它是如何限制的对象创建。 可能的其他解决方案是什么?优选地,以这种代码解决问题的方式。

+0

这并不是,它会在每次调用getRuntime时创建一个新实例 – UnholySheep

+1

您似乎在寻找的是“单例模式”,例如:[Wikipedia article](https:// en。 wikipedia.org/wiki/Singleton_pattern)以获得更多信息(以及一个非常简单的例子) – UnholySheep

+0

我发现了这篇关于单例模式的文章:https://www.javaworld.com/article/2073352/core-java/simply-singleton。 html – esprittn

回答

0

你已经发布的代码似乎是错误的。这不是一个单身人士课程。每次调用getRuntime()时,都会创建一个新实例。相反,在getRuntime方法中,应该直接返回'r'(在静态块中初始化)。

如果您正在寻找Singleton模式,看看下面的实现。所有的 https://en.wikipedia.org/wiki/Singleton_pattern#Lazy_initialization

0

首先你问是一个很常见的问题。很常见,它被称为“单身模式”,你可以搜索它,你会发现更多的信息。至于你的代码,它几乎是好的。您getRuntime()方法更改为这一点,你会被罚款(从getRuntime()删除线r1=Runtime.getRuntime();

static Runtime getRuntime(){ 
     return r; 
    } 

现在有到instanciating辛格尔顿2种主要的方法 - 急切和懒惰。

  1. Eager意味着您的单例将在您的应用程序启动时立即执行。这就是你所做的。大“亲”是它海峡前进和简单。如果你的Singleton有很大的占用空间并且需要很长的时间来初始化,那么你的应用程序会在“需要”之前“浪费”内存,并且需要更长的时间才能初始化。
  2. 懒意味着,只有当它实际上是要求首次您辛格尔顿被创建。 “优点”:您的Singleton dos不会延迟您的应用程序启动时间并节省内存。 “Con”:执行过程复杂而且严重。搜索网页查看原因。
    但是,如果你使用一些框架(例如Spring)来管理所有的实例,那么你所需要做的就是说一个特定的类必须是一个单例,并且懒惰地执行,所以没有复杂性

    基本上,建议是,如果你可以负担得起你的辛格尔顿急切(即该方法的缺点是可以容忍的),那就用这种方法。如果此方法由于某些原因而不被接受,请使用Lazy instanciation
0

在JVM的引擎下,您无法真正“阻止”创建一个类的多个实例。另一方面,你有时想在代码中的任何地方使用同一个对象是很常见的,因为只有一个实例是没有意义的。所以人们提出了“单身人士”的想法。

在Java中,单身由把戏,利用“静态”修饰符的实现。通过将某些东西标记为“静态”,您告诉编译器您希望让该类的所有实例共享一个副本。这使得每个类的字段而不是每个实例。所以除非你自定义类加载器或类似的东西,否则这意味着你在整个JVM中都有一个单独的拷贝。

此外,你需要一个构造函数私有,让其他的代码不能只是调用构造函数来创建另一个实例。

但是,您应该记住,这只是编译器强制执行的一个“cosmetical”限制。认为它是一种很好的编程方式。例如,仍然可以通过反射创建其他对象。

0

一个非常基本实现真正的辛格尔顿是这样的:

public class Runtime { 

    // a single(ton) instance to limit the instantiation to 1 
    private static Runtime runtimeInstance; 

    // a private constructor, not accessable from outside this class! 
    private Runtime() { 
     System.out.println("First creation of a Runtime instance."); 
    } 

    // the method that actually provides a single instance to callers 
    public static Runtime getInstance() { 
     // if the instance is not yet instanciated 
     if (runtimeInstance == null) { 
      // instanciate it with the private constructor 
      runtimeInstance = new Runtime(); 
     } 
     // return the instance 
     return runtimeInstance; 
    } 
} 

因此您可以通过

Runtime runtime = Runtime.getInstance(); 

它总是给你一个实例调用的对象。

+1

绝对是一个错误的例子。有几个线程可以同时检查条件“if(runtimeInstance == null)”,而它仍然是空的,然后每个线程都会创建一个新的实例。这是一个经典的例子,如何不写Singleton –

+0

我应该指出,这个例子只是为了了解Singleton的基本知识,因为这个问题根本不是关于不同的线程。我为你的评论投票,因为你是对的,但在这个问题的背景下,你的建议可能会有点太多的开销... – deHaar

+0

我明白你的观点,但不同意。 Singleton基本上意味着多线程环境,但我认为这是辩论的一个公平点。在任何情况下,你都会非常喜欢加尔兰特和大部分人对你的答案表示赞赏。谢谢。 –