【问题标题】:the concept of STATIC variables, and methods in Java [closed]Java中的静态变量和方法的概念[关闭]
【发布时间】:2018-07-07 14:04:43
【问题描述】:

我一直在拼命寻找明确的答案,我想我有点明白了,但同时我不太明白这个关键字的广义概念,静态。

这是我制作的场景:

package oops;

public class Math {

boolean notNumber = false;
static boolean notString = false;

public static void main(String[] args) {

    int num1 = 1;
    static int num2 = 1; //doesn't work

    Math math = new Math();
    math.notNumber = true;

    notNumber = true; //doesn't work
    notString = true;
}

public void whatever() {
    notNumber = true;
}

}
  1. 为什么不能在静态方法(或任何方法)内将变量声明为静态? “范围”是什么意思?我知道静态变量与类的特定实例无关,它更像是一个“全局”变量。但是为什么不能在方法内部创建静态变量(num2),却可以使用静态变量(notString)呢?

  2. 当你制作静态变量时,你必须在类中制作它们吗?方法中不可能?

  3. 由于我将 notNumber 声明为非静态,我知道我必须创建一个对象来访问该变量。但是为什么它在whatever()中没有任何创建对象的情况下可以工作,而在静态方法main()中却不行?

【问题讨论】:

标签: java scope static


【解决方案1】:

但是为什么不能在方法中创建一个静态变量(num2), 但是可以使用静态变量(notString)吗?

当你制作静态变量时,你必须在课堂上制作它们吗? 方法中不可能?

static 作用于类上下文。所以在方法范围内声明static 变量是没有意义的。
这就像您在方法中声明了一个实例字段。
声明一个变量和使用它是两个不同的事情,不遵守相同的规则。
根据经验,您在适合此修饰符的位置声明具有特定修饰符的变量。例如:

  • 类顶层的实例和静态字段
  • 方法级别的局部变量

并且您在与此修饰符兼容的任何上下文中使用具有特定修饰符的变量:

  • 实例上下文中的实例变量
  • 实例和静态上下文中的静态变量。

由于我将 notNumber 声明为非静态的,我知道我必须创建一个 对象来访问该变量。但是为什么它在任何()中都有效 没有创建任何对象,但不在静态方法 main() 中?

这是一个实例方法:

public void whatever() {
    notNumber = true;
}

所以访问类的实例成员是有效的。

而另一个是static 方法。所以它可以引用static 字段但不能引用实例字段:

public class Math {

   boolean notNumber = false; // instance
   static boolean notString = false; // static

    public static void main(String[] args) {

        ...    
        notNumber = true; //doesn't work as refers an instance field
        notString = true; // work as refers a static field
    }
  ...
 }

【讨论】:

  • 感谢您深思熟虑的回答,请问您在回答中提到的“实例字段”是什么,“就像您在方法中声明了实例字段一样。”不是实例=对象吗?所以基本上是非静态的?
  • 不客气。那确实是一个对象。在您的实际代码中:boolean notNumber = false; 是一个实例字段。并且类的每个实例在实例字段方面都有自己的状态。
【解决方案2】:

因为绝对不需要在方法中声明static viriablesstatic variables 是该类的所有实例共享的成员。假设允许在main方法中声明它,而你还有另一个静态方法foo,那你怎么能在foo中访问这个变量呢?

【讨论】:

    【解决方案3】:
    1. 您似乎明白静态成员不属于任何实例。它们属于 本身。它们并不像您所说的那样真正“全球化”。当您想从另一个类访问它们时,您仍然需要先编写类名。因为静态成员属于类,所以它们存在的唯一合理位置是类级别。您不能在方法中声明它们,因为这会使它们看起来像是属于方法(例如,它们的范围是方法体),而实际上它们不是。您可以在同一类的方法中使用它们而无需限定类名,因为该方法在类的范围内。

    2. 他们必须在课堂上,如上所述。

    3. 这是个好问题。如果你仔细看,whatever 也不是静态的!这意味着您必须先拥有一个实例,然后才能执行whatever。此实例在whatever 中称为“this”。您对notNumber 的使用是this.notNumber 的缩写。您正在使用调用whatever 的实例的notNumber 字段。

    【讨论】:

    • 感谢您周到的回答。只是为了澄清我的想法,你说,“当你想从另一个类访问它们时,你仍然需要先写类名。”是因为它是静态的吗?你只是去className.variable,像那样?因为如果它是非静态的,你将不得不创建一个对象并像这样,objectName.variable。对吗?
    • @KeKe 是的!如果您认为我的回答回答了您的问题,请考虑通过单击该复选标记接受它!
    【解决方案4】:

    让我们一一回答。但在此之前,让我们了解什么是静态变量,什么是非静态变量。静态变量是属于一个类而不属于该类的任何特定实例的变量,而另一方面,一个非静态变量属于一个类实例。

    所以考虑下面的例子

    class A{
    static Object someStaticValue;
    Object someNonStaticValue;
    }
    
    A.someStaticValue = new Object(); //allowed
    A.someNonStaticValue = new Object() //not allowed as someNonStaticValue belongs to instance of A and will be different for each instance of A
    A objectA = new A();
    objectA.someNonStaticValue = new Object(); //allowed as this will update someNonStaticValue which is in scope of objectA
    
    objectA.someStaticValue = new Object(); //allowed as it will simply update the value of variable in Class scope.
    
    A objectB = new A();
    objectB.someNonStaticValue = new Object(); //allowed
    objectB.someStaticValue = new Object(); //allowed as it will simply update the value of variable in Class scope.
    

    objectA.someNonStaticValue 不等于 objectB.someNonStaticValue 因为它们属于两个不同的范围

    A.someStaticValue, objectA.someStaticValue, objectB.someStaticValue -> 所有人都在更新 类范围内的变量。

    现在来回答你的问题:

    为什么不能在静态或非静态方法中声明静态变量?

    在方法内声明的任何变量都将在方法内具有作用域,因此永远不能属于一个类。每次调用该方法时都会使用一个新实例,因此每次调用都会有所不同,因此没有目的在方法中将变量设为静态

    当你制作静态变量时,你必须在课堂上制作它们吗? 方法中不可能?

    是的,因为在方法中创建不会解决任何问题,并且无法保持静态的定义,因为值会在对该方法的不同调用中发生变化。

    由于我将 notNumber 声明为非静态的,我知道我必须创建一个 对象来访问该变量。但是为什么它在任何()中都有效 没有创建任何对象,但不在静态方法 main() 中?

    因为在whatever()函数中,可以确定你已经创建了一个你调用这个函数的类的新实例,所以允许在非静态变量中调用非静态变量。此外,在这种情况下,JVM 清楚该变量使用哪个实例范围。但是,当涉及到静态方法时,不能保证该类的实例是否已创建,也不保证该非静态变量使用哪个类实例范围。因此,不允许从静态方法调用非静态变量。

    【讨论】:

    • 非常非常好的答案,现在我明白了,该死的!!
    【解决方案5】:

    为什么不能在静态方法(或任何方法)内将变量声明为静态? “范围”是什么意思?我知道静态变量与类的特定实例无关,它更像是一个“全局”变量。但是为什么不能在方法内部创建静态变量(num2),却可以使用静态变量(notString)呢?

    回答:您不能在方法内将变量声明为静态。 在方法内部,所有变量都是局部变量,在此方法之外不存在,这就是为什么它们不能是静态的。

    但为什么它在whatever() 中有效?

    回答:因为 boolean notNumber 在类级别声明,任何方法都是非静态的,这就是原因。你不能在静态中引用非静态

    为什么不能在静态中引用非静态? Why non-static variable cannot be reference from a static context - reg

    当你制作静态变量时,你必须在类中制作它们吗?在方法中不可能?

    回答你不能在静态方法中创建静态变量。 查看第一个答案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2012-10-24
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      相关资源
      最近更新 更多