【问题标题】:Java - Can't declare object in static classJava - 无法在静态类中声明对象
【发布时间】:2013-01-28 15:37:49
【问题描述】:

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

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

我已经四处搜索,但没有人为我编译单例模式。顺便说一句,我正在使用处理(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;
  }
}

【问题讨论】:

标签: java singleton static-methods


【解决方案1】:

标准的单例模式是有一个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;
  }
}

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

【讨论】:

    【解决方案2】:

    timer 在 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;
      }
    }
    

    您还缺少这两种方法的公共限定符。

    【讨论】:

      【解决方案3】:

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

      static public class DemoSystem {
      

      应该是:

      public class DemoSystem {
      

      而且,没有 100%,可能有语法错误(您缺少分号...):

         protected DemoSystem() {}
      

      应该是

         protected DemoSystem() {};
      

      【讨论】:

        【解决方案4】:

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

        所以以下是无效的

        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;
            }
        }
        

        【讨论】:

          【解决方案5】:

          贴出的源代码sn-p有几点相关。

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

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

          或正确同步方法。

          1. 制作Timer timer,一个类级变量。

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

          所以最终的代码将如下所示:

          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;
              }
          }
          

          【讨论】:

          • 编译失败。我收到错误“无法将字段实例声明为静态;静态字段只能在静态或顶级类型中声明。”你认为这是处理的限制吗?顺便说一句,我正在使用我自己的 Timer 类。
          • 嗨,我认为这可能是处理的限制,因为我已经在 eclipse juno 中成功编译了相同的代码。
          • 你现在可以编译和运行你的代码了吗?如果不是,请告诉您使用哪个 IDE 和处理插件进行开发。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-09-30
          • 2010-11-07
          • 1970-01-01
          • 2018-09-14
          • 2018-01-12
          • 2013-06-19
          相关资源
          最近更新 更多