非静态方法能修改静态变量吗?

27

我想知道一个非静态方法如何修改一个静态变量。我知道静态方法只能访问其他静态方法和静态变量。但是,另一面是否正确?非静态方法只能访问非静态变量吗?例如:

public class SampleClass {
  private static int currentCount = 0;

  public SampleClass() {
    currentCount++;
  }

  public void increaseCount() {
    currentCount++;
  }
}

这段代码可以编译,我想知道它在静态访问权限方面的原因。


7
你试过了吗? - Marco Forberg
3
是的,它可以编译。只是想知道是否有人在任何地方记录了这一点,并且是否我推理正确。 - Brian
2
静态方法不能修改实例变量这种说法并不完全正确。只是它们没有隐式的“this”引用。你可以这样写:class Ex { private int x; static void fn(Ex ex) { ex.x = 12; } }。顺便说一句,可变的静态变量通常是一个坏主意。 - Tom Hawtin - tackline
1
回答问题:是的,他们可以;不,不要那样做。 - fge
9个回答

45

我从Java教程中找到了这篇文章。

  • 实例方法可以直接访问实例变量和实例方法。
  • 实例方法可以直接访问类变量和类方法。
  • 类方法可以直接访问类变量和类方法。
  • 类方法不能直接访问实例变量或实例方法,必须使用对象引用。此外,类方法不能使用关键字this,因为没有实例可供其引用。

因此,答案是肯定的,非静态方法可以修改静态变量。


17

不,任何非静态方法都可以访问静态成员。唯一的例外情况是非静态上下文无法访问静态成员(例如静态成员对类是私有的,而非静态代码不在那个类中)。静态变量存在是为了提供一个无需实例的变量/方法,例如如果我们有一个Game类和一个highscore变量,那么highscore将是静态的(无需实例即可访问),并且在每局游戏(Game类的实例)完成后,如果我们的分数大于高分,则可以从非静态上下文中修改highscore。


谢谢你,我不知道私有变量的事情,这让我在这里感到头疼。 - A.Sanchez.SD

6
非静态方法可以访问静态变量。静态方法只能直接访问静态变量或方法,而无需创建对象。例如:public static void main(String arg[])

不使用对象,而是将其作为参数提供。 - user207421

1
非静态方法可以访问静态变量和静态方法,因为它们是类的成员。

演示代码

public class Static_Class {
    protected static String str;
    private static int runningLoop;

    static{
        str = "Static Block";
    }

    /**
     * Non-Static Method Accessing Static Member  
     */
    public void modifyStaticMember(){
        str = "Non-Static Method";      
    }

    /**
     * Non-Static Method invoking Static Method
     */
    public void invokeStaticMethod(){
        String[] args = {};
        if(runningLoop == 0){
            runningLoop++;
            main(args); 
        }
        //Exiting as it will lead to java.lang.StackOverflowError
        System.exit(0);
    }

    public static void main(String[] args) {
        Static_Class instance = new Static_Class();
        System.out.println(str);
        instance.modifyStaticMember();

        // Changed Value persists 
        System.out.println(str);

        //Invoking Static Method
        instance.invokeStaticMethod();

    }
}

0

静态变量是类变量而不是实例或局部变量。这就是为什么我们可以在非静态方法中使用静态变量的原因。静态变量不是针对每个对象的,它们只有一个副本,将在整个程序中使用。


0

静态成员不是实例成员,它们由类共享,因此基本上任何实例方法都可以访问这些静态成员。


0

静态方法不能修改非静态字段-使用非静态字段(在类外部)必须实例化类对象, 但是对于使用静态方法,根本不需要实例化对象。 这就是为什么非静态方法(不需要对象实例化)修改应该被实例化的字段是不合理的原因。

因此-静态方法只能触及静态字段(或调用其他静态方法)。

但正如您所提到的,反之亦然, 非静态方法可以修改其类的所有对象都是静态的静态字段。


如果我们有该类的静态实例,那么我们可以使用该静态对象来修改非静态字段。我理解得对吗? - BharatProteemGogoi

0
看看这个。静态变量可以通过多种方式访问。其中最常见的一种是在变量名前加上类名,因为静态变量是每个类的。由于您在同一类中引用此变量,因此您不必在变量名前加上类名。静态变量在哪里调用都无所谓。此外,这是一个私有静态变量,其他任何类都无法访问它。

-1

是的,静态方法可以访问非静态变量。这可以通过创建一个类对象并通过该对象访问变量来实现。在下面的示例中,main是一个静态方法,它访问变量a,该变量是一个非静态变量。

演示代码:

public class Sample {

   private int a;

   void method()
   {
       System.out.println("i am a private method");
   }

   public static void main(String[] args)
   { 
       Sample sample=new Sample();
       sample.a=10;
       System.out.println(sample.a);
   }
}   

问题可能是反过来的。从非静态方法访问静态变量。 - Pramod Setlur
抱歉,但我认为你的说法“是的,静态方法可以访问非静态变量”是不正确的。就一般情况而言,在你的例子中,“main”函数并不是一个类的方法,而是一个带有“main”关键字的特殊函数。许多专家已经说过两件事:(1)静态方法不能访问或修改类的非静态数据成员。静态方法只能访问或修改类的静态数据成员。(2)非静态方法可以修改类的静态和非静态数据成员。 - Job_September_2020

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接