static 关键字是否阻止将新对象分配给变量?

Does the static keyword prevent new objects from being assigned to the variable?

给定以下代码:

class Demo {                    
    static String s = "123";    

    static void m1(String s) {
        this.s = s;             
    }

    void m2(String s) {
        this.s = s;              
    }
}

class Hello {
    public static void main(String args) {
        Demo.m1("456");          
        Demo d = new Demo();       
        d.m2("789");         
    }
 }

我想知道在创建对象时使用实例变量和静态变量有什么区别:

  1. 鉴于字符串是不可变的,变量s是静态的,为变量s创建了多少个对象?

  2. 调用m1()等静态方法时是否创建了新对象?

  3. 调用m2()等实例方法时是否创建了新对象?


已编辑:

我对静态关键字的假设是错误的。现在我清楚了。

  1. static 是关键字。
  2. 用于声明class的成员。
  3. 静态成员属于 class.
  4. 不能在静态上下文中使用实例变量。
  5. 此关键字不能在静态上下文中使用。
  6. 无需创建对象即可访问静态成员。
  7. 静态变量在 class 加载到内存中时生效。
  8. 此关键字只能用于访问实例成员。
  9. 此关键字用于访问同一class内class的成员。

感谢您的帮助。下面是编辑后的代码:

class Demo {                    
    static String s= "123";  //Static variable
    String s1 ="abc"; // Instance variable  

    static void m1(String s) {
        Demo.s = s; //Accessing an static variable       
    }

    void m2(String s,String s1) {
        Demo.s = s; 
        this.s1 = s1;//Accessing an instance variable           
    }
}

class Hello {
    public static void main(String args[]) {
        Demo.m1("456");          
        Demo d = new Demo();       
        d.m2("789","xyz");         
    }
}

只创建了一个static String(这是static背后的基本思想)。因此,通过调用 Demo.m1("353"),您将 s 更改为"353",通过创建一个新的 Demo d,并调用 d.m2("344"),您将用“344”覆盖内容“353”。

我对这个问题有点困惑,因为您可以使用

轻松地自行测试
public void talk(){
    System.out.println("my static string s is: "+s)
}

并在程序的不同阶段打印 s。你想知道为什么会发生这种情况吗?

这可能对您有所帮助: Immutability of Strings in Java

static 修饰符仅表示变量是 class 的成员,而不是特定实例的成员。与是否创建新对象无关

首先对您的代码进行一些观察:

方法m1():

static void m1(String s) {
    this.s = s;
}

这不会编译,因为您不能从静态方法中引用实例变量。应该是:

static void m1(String s) {
    Demo.s = s;
}

方法m2():

void m2(String s) {
    this.s = s;
}

现在这不会给你一个编译错误,但应该给你一个警告。 this 应该只用于实例属性和方法。由于 s 是一个 class 属性,您应该使用 class 的名称来代替:

void m2(String s) {
    Demo.s = s;
}

现在我们可以对代码进行推理了:

  1. 当您执行 static String s = "123" 时,您会创建一个新的 String 并使 s 指向它,因此 s -> "123".

  2. 当你调用Demo.m1("456")的时候,你又创建了一个String,这次"456",让s指向它,所以s -> "456".

  3. 当您调用 d.m2("789") 时,您再次创建一个 String 对象 "789",并使 s 指向它,因此 s -> "789".

因此,您总共创建了 3 个 String 个对象。