public static void main() 访问非静态变量

Posted

技术标签:

【中文标题】public static void main() 访问非静态变量【英文标题】:public static void main () access non static variable 【发布时间】:2012-07-16 08:19:00 【问题描述】:

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

【问题讨论】:

静态方法不能访问非静态字段,但当然可以在方法本身中定义局部变量(并通过那些访问非静态字段)。请举例说明。 【参考方案1】:

不,它没有。

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

【讨论】:

公共类 A public static void main(String[] args) int a = 2; System.out.println(a); // 这行得通! 我的问题是 tis 是如何工作的【参考方案2】:

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

例子:

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


class Example 
    public int variable;

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

相关问题:

Accessing non-static members through the main method in Java

更新:

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

在代码中

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

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

【讨论】:

'public class A public static void main(String[] args) int a = 2; System.out.println(a); // 这行得通! ' 这不使用任何实例【参考方案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# 纠正的缺陷之一……)

【讨论】:

那么如果静态方法和变量不在定义它们的类中,它们在哪里包含? when static variables are initialized in Java. 所以 main 可以访问 instanceMethod 和 instanceVariable 的唯一方法是它是否创建了 Demo 类的对象? 如果instanceMethodinstanceVariable 分别是实例方法和实例变量,那么它们只能通过静态方法被它们各自的对象解引用来访问类。【参考方案4】:

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

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:
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.
    

【讨论】:

以上是关于public static void main() 访问非静态变量的主要内容,如果未能解决你的问题,请参考以下文章

为什么 main 方法是 public static void ?

为什么main方法是public static void?

关于public static void main(String[] args)方法?

为什么Java的main方法必须是public static void?

将 main 方法定义为:public static void main(String[] args)的理由

public static void main(string[] args)解释