В нем сказано, что нестатические переменные не могут использоваться в статическом методе. Но public static void main does.How??
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
или нет.
Ответ 2
Да, основной метод может получить доступ к нестационарным переменным, но только косвенно через фактические экземпляры.
Пример:
public class Main {
public static void main(String[] args) {
Example ex = new Example();
ex.variable = 5;
}
}
class Example {
public int variable;
}
Что означают люди, когда говорят, что "нестатические переменные не могут использоваться в статическом методе" - это то, что нестатические члены одного и того же класса не могут быть напрямую доступны (как показано в ответ Keppils).
Связанный вопрос:
Update:
Говоря о нестатических переменных, одно неявно означает переменные-члены. (Так как локальные переменные в любом случае не могут иметь статического модификатора.)
В коде
public class A {
public static void main(String[] args) {
int a = 2;
System.out.println(a); // this works!
}
}
вы объявляете локальную переменную (которая обычно не называется нестатической, даже если она не имеет статического модификатора).
Ответ 3
Основной метод также не имеет доступа к нестационарным элементам.
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" еще не созданы.
В этом смысле статический метод не является частью экземпляра объекта класса, который его содержит. Это идея классов полезности.
Чтобы вызвать любой нестатический метод или переменную в статическом контексте, вам нужно сначала построить объект с помощью конструктора или factory, как и в любом случае вне класса.
Дополнительная глубина:
В основном это недостаток в дизайне 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 могут быть настроены для выдачи предупреждения или ошибки для кода, подобного этому - вы не должны этого делать, так как это ущемляет читаемость. (Это один из недостатков, который был исправлен С#...)
Ответ 4
** Здесь вы можете увидеть таблицу, которая очищает доступ к статическим и нестатическим элементам данных в статических и нестатических методах. **
Ответ 5
Вы можете создавать нестатические ссылки в статических методах, например:
static void method() {
A a = new A();
}
То же самое мы делаем в случае метода public static void main(String[] args)