14

它说非静态变量不能在静态方法中使用。但是 public static void main 可以。那是怎么回事?

4

6 回答 6

26

不,它没有。

public class A {
  int a = 2;
  public static void main(String[] args) {
    System.out.println(a); // won't compile!!
  }
}

public class A {
  static int a = 2;
  public static void main(String[] args) {
    System.out.println(a); // this works!
  }
}

或者如果你实例化A

public class A {
  int a = 2;
  public static void main(String[] args) {
    A myA = new A();
    System.out.println(myA.a); // this works too!
  }
}

public class A {
  public static void main(String[] args) {
    int a = 2;
    System.out.println(a); // this works too!
  }
}

会起作用,因为a这里是局部变量,而不是实例变量。在方法执行期间,方法局部变量始终是可访问的,无论该方法是否static存在。

于 2012-07-17T12:01:54.133 回答
10

是的, main 方法可以访问非静态变量,但只能通过实际实例间接访问。

例子:

public class Main {
    public static void main(String[] args) {
        Example ex = new Example();
        ex.variable = 5;
    }
}

class Example {
    public int variable;
}

当人们说“非静态变量不能在静态方法中使用”时,人们的意思是不能直接访问同一类的非静态成员(例如Keppils 的答案所示)。

相关问题:


更新:

在谈论非静态变量时,隐含的意思是成员变量。(因为无论如何局部变量都不可能有静态修饰符。)

在代码中

public class A {
    public static void main(String[] args) {
        int a = 2;
        System.out.println(a); // this works!
    }
}

您正在声明一个局部变量(即使它没有静态修饰符,它通常也不称为非静态变量)。

于 2012-07-17T12:03:17.770 回答
3

main 方法也不能访问非静态成员。

final public class Demo
{
   private String instanceVariable;
   private static String staticVariable;

   public String instanceMethod()
   {
      return "instance";
   }

   public static String staticMethod()
   {
      return "static";
   }

   public static void main(String[] args)
   {
      System.out.println(staticVariable); // ok
      System.out.println(Demo.staticMethod()); // ok

      System.out.println(new Demo().instanceMethod()); // ok
      System.out.println(new Demo().instanceVariable); // ok

      System.out.println(Demo.instanceMethod()); // wrong
      System.out.println(instanceVariable);         // wrong 
   }
}

这是因为默认情况下,当您调用方法或变量时,它实际上是在访问this.method()或 this.variable。但是在 main() 方法或任何其他静态方法() 中,还没有创建“this”对象。

从这个意义上说,静态方法不是包含它的类的对象实例的一部分。这就是实用程序类背后的想法。

要在静态上下文中调用任何非静态方法或变量,您需要首先使用构造函数或工厂来构造对象,就像在类之外的任何地方一样。


更多深度:

基本上,这是 Java IMO 设计中的一个缺陷,它允许引用静态成员(方法和字段),就好像它们是实例成员一样。这在这样的代码中可能会非常令人困惑:

Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);

看起来它正在让新线程进入睡眠状态,但它实际上编译成这样的代码:

Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);

因为sleep是一个静态方法,它只会让当前线程休眠。

实际上,甚至没有检查该变量的非空性(不再检查;我相信它曾经是):

Thread t = null;
t.sleep(1000);

一些 IDE 可以配置为对这样的代码发出警告或错误 - 你不应该这样做,因为它会损害可读性。(这是 C# 纠正的缺陷之一......)

于 2012-07-17T12:02:25.833 回答
3

**在这里您可以看到清除静态和非静态方法中静态和非静态数据成员访问的表格。**静态非静态表

于 2017-04-01T22:04:59.737 回答
0

您可以在静态方法中创建非静态引用,例如:

static void method() {
   A a = new A();
}

public static void main(String[] args)我们在方法的情况下做同样的事情

于 2012-07-17T12:04:40.827 回答
0
public class XYZ
{
   int i=0;
   public static void increament()
       {
       i++;   
       }
}
public class M
{
    public static void main(String[] args)
    {
    XYZ o1=new XYZ();
    XYZ o2=new XYZ();
    o1.increament(); 
    XYZ.increament(); //system wont be able to know i belongs to which object 
                  //as its increament method(static method)can be called using   class name system 
                  //will be confused changes belongs to which object.
    }
}
于 2018-08-01T02:27:10.870 回答