【问题标题】:Why private variable only increase one time even its called more than one为什么私有变量只增加一次,即使它被称为不止一次
【发布时间】:2018-04-17 11:13:45
【问题描述】:

我是 java 新手,我试图理解为什么 a 没有增加,即使 a++ 运行 3 次但只增加了一次。

为什么另外 2 个实例的行为与第一个实例不同,这是什么原理?

https://www.tutorialspoint.com/tpcg.php?p=Y0VNTH

  public class ClassicSingleton {
   private int a = 0;
   static int b = 0;
   private static ClassicSingleton instance = null;

   private ClassicSingleton() {

     a++; 
     System.out.println(a); 
     System.out.println("ClassicSingleton() called"); 

   }

   public static ClassicSingleton getInstance() {
      b++;
      System.out.println("b:"+b); 
      instance = new ClassicSingleton();

      return instance;
   }



    public static void main(String[] args) {
      ClassicSingleton tmp = ClassicSingleton.getInstance( );
      ClassicSingleton tmp2 = ClassicSingleton.getInstance( );
      ClassicSingleton tmp3 = ClassicSingleton.getInstance( );

   }
}

【问题讨论】:

    标签: java class static-members


    【解决方案1】:

    a 是一个实例变量,这意味着您在 main 方法中创建的三个 ClassicSingleton 类中的每一个都有自己的该变量副本,该变量初始化为 0(默认情况下)并由构造函数。

    顺便说一句,ClassicSingleton 在这里是一个误导性名称,因为您的 ClassicSingleton.getInstance() 在每次调用时都会返回一个新实例。即使它在每次调用中返回相同的实例,a 仍将包含 1(因为这次您将有一个 ClassicSingleton 实例,a 将只增加一次)。

    哦,如果你想让ClassicSingleton 成为一个真正的单身人士,请将getInstance 更改为:

    public static ClassicSingleton getInstance() {
        if (instance == null) {
            instance = new ClassicSingleton();
        }
        return instance;
    }
    

    【讨论】:

    • 基本上a in tmp, tmp2 and tmp3 是完全独立的,跨越这个类的所有实例。因此,您的单身人士根本不是单身人士,请检查例如。本教程用于澄清javaworld.com/article/2073352/core-java/simply-singleton.html 检查实例是否为空的范围
    • @Kad instance 变量应该只保留对单个实例的引用。这就是单例模式的重点——只创建一个类的实例。
    • @Eran 如果变量在每次创建实例时都获得第一个值,我们如何制作这样的单例? private static ClassicSingleton instance = null;链接:tpcg.io/C4Gim5
    • @Kad 好吧,你有b 变量,它跟踪getInstance 被调用的次数。在构造函数中增加一个变量(例如a)在单例类中是没有意义的,因为它只会增加一次。
    • @Eran 我不想让单例类名只保留在示例中
    【解决方案2】:

    有两个原因

    1. a 是一个实例变量,仅递增一次 - 在构造时
    2. 每次调用getInstance 时都会创建一个新实例,这会将共享实例替换为一个新实例。基本上,您已经错误地实现了经典的单例,而是实现了工厂方法。

    要修复单例,请检查instance 是否为空,并且仅在这种情况下创建一个新实例。

    【讨论】:

      猜你喜欢
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多