Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中一个类的多个静态实例?_Java_Memory_Static - Fatal编程技术网

Java中一个类的多个静态实例?

Java中一个类的多个静态实例?,java,memory,static,Java,Memory,Static,我是新来的,请不要介意你觉得这个问题很愚蠢。我在处理单例代码。我对它做了一点修改(我的问题与单例无关,是的,我删除了单实例检查)。我的问题是,尽管java中的类实例只能是一个,为什么输出中有两个静态类“实例”(见哈希)。我知道“new”关键字将给出一个新的内存地址(这就是在哈希中打印的内容),但是静态类实例不应该是一个吗?所以我得到两个哈希来打印对象实例,静态变量k具有相同的值,这很好 public class Singleton { private static Singleton

我是新来的,请不要介意你觉得这个问题很愚蠢。我在处理单例代码。我对它做了一点修改(我的问题与单例无关,是的,我删除了单实例检查)。我的问题是,尽管java中的类实例只能是一个,为什么输出中有两个静态类“实例”(见哈希)。我知道“new”关键字将给出一个新的内存地址(这就是在哈希中打印的内容),但是静态类实例不应该是一个吗?所以我得到两个哈希来打印对象实例,静态变量k具有相同的值,这很好

public class Singleton {

    private  static Singleton instance;
    static int k;


    public static Singleton getInstance(){
        try{
            instance = new Singleton();

            System.out.println(instance);
        }catch(Exception e){
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
        return instance;
    }

    public static void main(String[] ar) {
        Singleton c1=Singleton.getInstance();
        c1.k=1;
        Singleton c2=Singleton.getInstance();
        c2.k=2;
        System.out.println(c1.k);
        System.out.println(c2.k);

    }
}
输出:

Singleton@15db9742
Singleton@6d06d69c
2
2

你的单身汉不是这样的

每次调用getInstance都会生成一个新实例,而不是检查静态对象“instance”是否为空

这就是为什么你会得到这样的结果:

Singleton@15db9742 
Singleton@6d06d69c

它清楚地显示了Singleton类的两个实例,问题是在
getInstance
方法中,您总是创建一个新的实例对象

也就是说,虽然实际实例是
静态的
,即类属性,但每次调用
getInstance
时都会覆盖它

要解决这个问题,您应该检查
instance
是否为
null
,然后才创建一个新对象

if(instance == null)
  instance = new Stingleton();

return instance;

这是因为缺少只创建一次单例的保护

public static Singleton getInstance(){
  try{
    if(instance == null)
    {
      instance = new Singleton();
    }

    System.out.println(instance);
  } catch(Exception e){
   throw new RuntimeException("Exception occured in creating singleton instance");
  }
  return instance;
}

如果没有此保护,仍然只有一个静态实例,但此实例将被第二次覆盖。

您的变量
instance
在两个对象之间共享,但当您调用
instance=new Singleton()时,它指向的对象将发生更改

我猜你要找的是这个

public class Singleton {
    public static Singleton instance; //field is made public so we can print it from main class (just to debug)
    static int k;


    public static Singleton getInstance(){
        try{
            instance = new Singleton();
        }catch(Exception e){
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
        return instance;
    }

    public static void main(String[] ar) {
        Singleton c1=Singleton.getInstance();
        c1.k=1;
        Singleton c2=Singleton.getInstance();
        c2.k=2;

        //notice that both of the instance variables of c1 and c2 are printed
        //after we've initialized all of them.
        System.out.println(c1.instance);
        System.out.println(c2.instance);

        System.out.println(c1.k);
        System.out.println(c2.k);

    }
}
在这里,两个实例变量的值相同

输出

Singleton@6d06d69c
Singleton@6d06d69c
2
2

其思想是在初始化所有对象的
instance
变量后打印值。最近的初始化将覆盖所有以前的初始化。

如上所述,您的问题在于您没有保护您的实例化

另外,为了给@Ghislain Fourny的答案增加一点内容,确保您没有在多线程上下文中实例化2个类,请在方法getInstance中添加关键字“synchronized”


}

您想问什么?您的代码不是一个单例,每次调用
getInstance()
时都会生成一个新实例。
static
表示只有一个变量实例。它与您创建的对象实例的数量无关;您的问题似乎是基于对Java基础知识的理解不足。您的类中只有一个静态字段,其中包含您创建的最后一个实例。您将获得两个不同的实例,因为代码就是这样做的:每次调用
getInstance()
方法时创建一个新实例。它只是一个字段,可以随时(重新)分配。与非静态字段的区别在于,该字段由类拥有,而不是由该类的实例拥有。而
static Singleton s=new Singleton()
是完全允许的,只要该定义在类体中,而不是在方法体中。是的!你澄清了我的疑问。但是为什么允许new创建静态实例?@Vishal这取决于需求。让我们假设在您的类中,您想知道它被初始化了多少次。在这种情况下,静态实例很方便,因为我们可以创建一个名为
private static int counter=0
的字段,并在类的构造函数中递增它。由于此
计数器
变量将在所有对象之间共享,因此同一变量将统计所有实例。如果我们不将其设为静态,则每次初始化一个对象时,都会创建一个新的
计数器实例,它将从零开始。是的!你澄清了我的疑问。但是为什么静态被允许用new初始化呢?我的意思是,既然对象不应该在静态上下文中使用,我在这里用new Singleton()初始化“instance”;此外,Singleton.class可以直接使用。不允许使用static Singleton s=new Singleton(),这是正确的。否。我们不能使用
Singleton.class
进行初始化,它表示类引用,并且不初始化对象。重点是静态变量需要一个对象来保持。这就是为什么我们使用new初始化它。不同之处在于,如果使用
new
初始化
static
变量,则相同的对象将在所有实例中共享,而如果不将其设为static,则所有新对象都将以null开头。@Vishal是的,这是java语言规范施加的限制。您不能在java中的任何方法中将任何字段声明为静态字段。只有类变量(字段)和方法可以是静态的。将此答案视为原因:
  public static synchronized Singleton getInstance(){ 
  try{ 
  if(instance == null) { 
      instance = new Singleton();
  }
      System.out.println(instance);
}catch(Exception e){
    throw new RuntimeException("Exception occured in creating singleton instance");
}
return instance;