STATIC变量的概念以及Java中的方法

时间:2018-07-07 14:04:44

标签: java scope static

我一直在拼命地寻找清晰的答案,我想我已经知道了,但是与此同时,我并没有完全理解该关键字的广义概念。

这是我所做的情况:

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声明为非静态的,所以我知道我必须创建一个对象来访问该变量。但是,为什么它在不创建任何对象的情况下在what()中起作用,但在静态方法main()中却不起作用?

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

  

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

     

创建静态变量时,是否必须在类中创建它们?   方法不可能吗?

static的作用域为类上下文。因此,在方法范围内声明static变量没有任何意义。
就像您在方法中声明实例字段一样。
声明变量并使用它是两个不遵循相同规则的截然不同的事情。
根据经验,可以在适合该修饰符的位置声明一个带有特定修饰符的变量。例如:

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

然后在与此修饰符兼容的任何上下文中使用带有特定修饰符的变量:

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

由于我将notNumber声明为非静态的,所以我知道我必须创建一个   对象访问该变量。但是为什么它在what()中起作用   没有任何对象的创建,但是不在静态方法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
    }
  ...
 }

答案 2 :(得分:1)

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

  2. 如上所述,它们必须在类中。

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

答案 3 :(得分:1)

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

因此请考虑以下示例

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.someStaticValueobjectA.someStaticValue,   objectB.someStaticValue->所有都相等,因为它们正在更新   类范围内的变量。

现在要问您的问题:

  

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

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

  

创建静态变量时,是否必须在类中创建它们?   方法不可能吗?

是的,因为在in方法中创建目标不会解决任何问题,并且将无法保持static的定义,因为在对该方法的不同调用中值会更改。

  

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

由于在what()函数中,请确保已创建该类的新实例,并使用该实例调用了此函数,从而允许在非静态变量内调用非静态变量。同样,在这种情况下,JVM可以清楚地知道该变量使用哪个实例范围。但是,当涉及到静态方法时,不能保证是否已创建该类的实例,也不能保证该非静态变量将使用哪个类实例范围。因此,不允许从静态方法调用非静态变量。

答案 4 :(得分:1)

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

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

但是为什么它可以在what()中使用?

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

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

创建静态变量时,是否必须在类中创建它们?无法使用这些方法吗?

ANSWER ,您不能在静态方法内创建静态变量。 查看第一个答案