Public static void main() доступ к нестационарной переменной

В нем сказано, что нестатические переменные не могут использоваться в статическом методе. Но public static void main does.How??

Ответ 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)