public static void main()访问非静态变量
它说非静态变量不能用在静态方法中。但是public static void main。如何?
不,它没有。
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
方法,在方法执行期间始终可以访问方法局部变量。
是的,main方法可以访问非静态变量,但只能通过实际实例间接访问。
例:
public class Main { public static void main(String[] args) { Example ex = new Example(); ex.variable = 5; } } class Example { public int variable; }
当人们说“非静态变量不能在静态方法中使用”时,人们的意思是不能直接访问同一类的非静态成员 (例如,如Keppils的答案所示)。
相关问题:
- 通过Java中的main方法访问非静态成员
更新:
在谈论非静态变量时,隐含地意味着成员变量 。 (因为无论如何局部变量都不可能有静态修饰符。)
在代码中
public class A { public static void main(String[] args) { int a = 2; System.out.println(a); // this works! } }
你正在声明一个局部变量(即使它没有静态修饰符,通常也不会被称为非静态变量)。
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);
看起来它正在发送新线程进入hibernate状态,但它实际上编译成如下代码:
Thread newThread = new Thread(runnable); newThread.start(); Thread.sleep(1000);
因为sleep
是一种静态方法,它只能使当前线程hibernate。
实际上,甚至没有检查变量的非无效性(更多;我相信它曾经是):
Thread t = null; t.sleep(1000);
某些IDE可以配置为对此类代码发出警告或错误 – 您不应该这样做,因为它会损害可读性。 (这是由C#纠正的缺陷之一……)
**在这里,您可以看到清除静态和非静态方法中静态和非静态数据成员访问的表。 **
您可以在静态方法中创建非静态引用,例如:
static void method() { A a = new A(); }
在public static void main(String[] args)
方法的情况下我们也这样做
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. } }