Java - 无法在静态类中声明对象

时间:2013-02-13 06:21:40

标签: java singleton static-methods

我正在尝试为System类实现单例模式。我发现的例子没有编译(例如http://www.tutorialspoint.com/java/java_using_singleton.htm)。在非静态类中有一个静态方法。所以我让这个类保持静态,一直都很好,直到我试图为我的Timer类创建一个成员变量。

现在我收到消息“无法访问类型为scene_3d的封闭实例。必须使用封闭实例限定分配...

我已经四处寻找,但没有人的单身模式为我编译。顺便说一句,我正在使用Processing(Java IDE /扩展)。任何关于如何解决这个问题的想法都会有很大的帮助。谢谢!

static public class DemoSystem {
  private static DemoSystem instance = null;  
  protected DemoSystem() {}

  public static DemoSystem Inst() {
    if( instance == null ) {
      instance = new DemoSystem();
    }
    return instance;
  }

  void init() {
    Timer timer = new Timer();  
  }

  int getTime() {
    return timer.elapsedTime;
  }
}

5 个答案:

答案 0 :(得分:2)

标准单例模式是拥有private构造函数和静态实例变量,因此:

public class DemoSystem {
  private static DemoSystem instance = null;
  private Timer timer;
  protected DemoSystem() {}

  public static DemoSystem Inst() {
    if( instance == null ) {
      instance = new DemoSystem();
    }
    return instance;
  }

  void init() {
    timer = new Timer();  
  }

  int getTime() {
    return timer.elapsedTime;
  }
}

修复导入后,这应该可以正常工作。

答案 1 :(得分:1)

计时器在init中声明。它必须在类中,因此get方法可以访问它,例如:

static public class DemoSystem {
  private static DemoSystem instance = null;
  private Timer timer;
  protected DemoSystem() {}

  public static DemoSystem Inst() {
    if( instance == null ) {
      instance = new DemoSystem();
    }
    return instance;
  }

  public void init() {
    timer = new Timer();  
  }

  public int getTime() {
    return timer.elapsedTime;
  }
}

你也错过了这两种方法的公共限定词。

答案 2 :(得分:1)

我认为您不能将整个课程声明为静态:

static public class DemoSystem {

应该是:

public class DemoSystem {

也没有100%可能有语法错误(你缺少分号......):

   protected DemoSystem() {}

应该是

   protected DemoSystem() {};

答案 3 :(得分:1)

首先,我认为顶级类不能是静态的,最初没有嵌套类,你不能向任何类添加静态。

所以关注无效

static public class DemoSystem {

 ...
}

你必须改变是喜欢

public class DemoSystem {
  private static DemoSystem instance = null;
  private Timer timer;
  protected DemoSystem() {}

  public static DemoSystem Inst() {
    if( instance == null ) {
      instance = new DemoSystem();
    }
    return instance;
  }

  void init() {
    timer = new Timer();  
  }

  int getTime() {
    return timer.elapsedTime;
  }
 }

最好将Enum用于单身人士。来自“Effective Java”

  

“这种方法在功能上等同于公共字段方法,除了它更简洁,免费提供序列化机制,并提供防止多个实例化的铁定保证,即使面对复杂的序列化或反射攻击。这种方法尚未被广泛采用,单元素枚举类型是实现单例的最佳方式。

因此,使用Enum您的课程如下:

public enum DemoSystem {
    INSTANCE;
    private Timer timer;
    void init() {
       timer = new Timer();  
     }

    int getTime() {
       return timer.elapsedTime;
    }
}

答案 4 :(得分:1)

有一些与发布的原始代码段有关的要点。

  1. 首先,顶级类不能声明为静态。

  2. 您创建的公共方法(公共静态DemoSystem Inst())不会保证只有在并发时它才会创建单例对象。 为此,在声明时初始化对象,如: private static DemoSystem instance = new DemoSystem();

  3. 或正确同步该方法。

    1. 制作定时器计时器,一个班级变量。

    2. 什么是timer.elapsedTime。我不认为Timer类中有任何这样的属性。 如果您使用不同的api,请进行必要的导入。

    3. 所以最终的代码如下所示:

      import java.util.Timer;
      
      public class DemoSystem {
          // Declared the variable at class level.
          Timer timer = null;
      
          // Initializing the object here only.
          private static DemoSystem instance = new DemoSystem();
      
          // Made the constructer private.
          private DemoSystem() {
          }
      
          // Static method to get singleton instance
          public static DemoSystem Inst() {
              return instance;
          }
      
          void init() {
              timer = new Timer();
          }
      
          int getTime() {
              //commented the statement so to compile the class  
              //return timer.elapsedTime;
              return 1;
          }
      }