Нестатическая переменная не может ссылаться на статический контекст

Я написал этот тестовый код:

class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}

Но это приводит к следующей ошибке:

Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^

Как мне получить мои методы для распознавания переменных класса?

Ответ 1

Вы должны понимать разницу между классом и экземпляром этого класса. Если вы видите машину на улице, вы сразу же знаете, что это автомобиль, даже если вы не можете видеть, какую модель или тип. Это потому, что вы сравниваете то, что видите с классом "автомобиль". Класс содержит то, что похоже на все автомобили. Подумайте об этом как о шаблоне или идее.

В то же время автомобиль, который вы видите, является экземпляром класса "автомобиль", поскольку он обладает всеми свойствами, которые вы ожидаете: есть кто-то за рулем, у него есть двигатель, колеса.

Итак, класс говорит, что "все автомобили имеют цвет", и экземпляр говорит, что "этот конкретный автомобиль красный".

В мире OO вы определяете класс и внутри класса, вы определяете поле типа Color. Когда экземпляр класса создается (когда вы создаете конкретный экземпляр), память зарезервирована для цвета, и вы можете присвоить этому конкретному экземпляру цвет. Поскольку эти атрибуты являются специфическими, они нестатические.

Статические поля и методы совместно используются всеми экземплярами. Они предназначены для значений, которые относятся к классу, а не к конкретному экземпляру. Для методов это обычно глобальные вспомогательные методы (например, Integer.parseInt()). Для полей это обычно константы (например, типы автомобилей, то есть что-то, где у вас ограниченный набор, который не меняется часто).

Чтобы решить вашу проблему, вам нужно создать экземпляр экземпляра (создать объект) своего класса, чтобы среда выполнения могла зарезервировать память для экземпляра (в противном случае разные экземпляры переписывают друг друга, чего вы не хотите).

В вашем случае попробуйте этот код как начальный блок:

public static void main (String[] args)
{
    try
    {
        MyProgram7 obj = new MyProgram7 ();
        obj.run (args);
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
}

// instance variables here

public void run (String[] args) throws Exception
{
    // put your code here
}

Новый метод main() создает экземпляр класса, который он содержит (звучит странно, но поскольку main() создается с классом вместо экземпляра, он может это сделать), а затем вызывает метод экземпляра ().

Ответ 2

Статические поля и методы связаны с самим классом, а не с его экземплярами. Если у вас есть класс A, "нормальный" метод b и статический метод c, и вы создаете экземпляр a вашего класса A, вызовы Ac() и ab() являются действительными. Метод c() не знает, какой экземпляр подключен, поэтому он не может использовать нестатические поля.

Решением для вас является то, что вы либо делаете свои поля статическими, либо ваши методы нестатичными. Тогда вы можете выглядеть так:

class Programm {

    public static void main(String[] args) {
        Programm programm = new Programm();
        programm.start();
    }

    public void start() {
        // can now access non-static fields
    }
}

Ответ 3

Ключевое слово static изменяет жизненный цикл метода или переменной в классе. static метод или переменная создается во время загрузки класса. Метод или переменная, которая не объявлена как static, создается только тогда, когда экземпляр класса создается как объект, например, с помощью оператора new.

Жизненный цикл класса в широком смысле:

  1. исходный код для класса написан, создавая шаблон или шаблон или штамп, который затем может быть использован для
  2. создать объект с оператором new используя класс, чтобы сделать экземпляр класса действительным объектом, а затем, когда это будет сделано с объектом
  3. уничтожить объект, освободив ресурсы, которые он содержит, такие как память, во время сборки мусора.

Чтобы иметь начальную точку входа для приложения, Java приняла соглашение, что программа Java должна иметь класс, который содержит метод с согласованным или специальным именем. Этот специальный метод называется main(). Поскольку метод должен существовать независимо от того, был ли создан экземпляр класса, содержащего метод main, метод main() должен быть объявлен с модификатором static, чтобы после загрузки класса метод main() доступен.

В результате, когда вы запускаете свое Java-приложение из командной строки, такой как java helloworld происходит ряд действий. Прежде всего, виртуальная машина Java запускается и инициализируется. Затем файл helloworld.class, содержащий скомпилированный код Java, загружается в виртуальную машину Java. Затем виртуальная машина Java ищет метод в классе helloworld который называется main(String [] args). этот метод должен быть static чтобы он существовал, даже если класс на самом деле не был создан как объект. Виртуальная машина Java не создает экземпляр класса, создавая объект из класса. Он просто загружает класс и начинает выполнение с метода main().

Поэтому вам нужно создать экземпляр вашего класса как объект, а затем вы можете получить доступ к методам и переменным класса, которые не были объявлены с помощью модификатора static. Как только ваша Java-программа запускается с функцией main() вы можете использовать любые переменные или методы, которые имеют модификатор static поскольку они существуют как часть загружаемого класса.

Однако те переменные и методы класса, которые находятся за пределами метода main() и не имеют static модификатора, не могут использоваться, пока экземпляр класса не будет создан как объект в методе main(). После создания объекта вы можете использовать переменные и методы объекта. Попытка использовать переменные и методы класса, которые не имеют static модификатора, без прохождения через объект класса, перехватывается компилятором Java во время компиляции и помечается как ошибка.

import java.io.*;

class HelloWorld {
    int myInt;      // this is a class variable that is unique to each object
    static int myInt2;  // this is a class variable shared by all objects of this class

    static void main (String [] args) {
        // this is the main entry point for this Java application
        System.out.println ("Hello, World\n");
        myInt2 = 14;    // able to access the static int
        HelloWorld myWorld = new HelloWorld();
        myWorld.myInt = 32;   // able to access non-static through an object
    }
}

Ответ 4

Сначала проанализируйте свою программу. В вашей программе первый метод main(), и помните, что это статический метод... Затем вы объявляете локальную переменную для этого метода (compareCount, low, high и т.д.). Область действия этой переменной - это только объявленный метод, независимо от того, что это статический или нестационарный метод. Таким образом, вы не можете использовать эти переменные вне этого метода. Это основная ошибка, сделанная вами.

Затем мы переходим к следующей точке. Вы сказали, что статичность убивает вас. (Это может убить вас, но это дает жизнь вашей программе!) Сначала вы должны понять основную вещь. * Статический метод вызывает только статический метод и использует только статическую переменную. * Статическая переменная или статический метод не зависят от какого-либо экземпляра этого класса. (т.е. если вы измените любое состояние статической переменной, оно будет отражено во всех объектах класса) * Из-за этого вы называете это переменной класса или методом класса. И многое другое о "статическом" ключевом слове. Надеюсь, теперь у вас есть идея. Сначала измените область действия переменной и объявите ее как статическую (чтобы использовать ее в статических методах).

И совет для вас: вы неправильно поняли идею сферы переменных и статических функций. Получите ясное представление об этом.

Ответ 5

Самая простая вещь - статические переменные или статические методы находятся на уровне класса. Переменные или методы уровня класса загружаются до методов или переменных уровня экземпляра. И, очевидно, вещь, которая не загружена, не может быть использована. Поэтому java-компилятор, не позволяющий обрабатывать вещи во время выполнения, решает во время компиляции. То, почему он дает вам ошибку, нестатические вещи не могут быть переданы из статического контекста. Вам просто нужно ознакомиться с областью уровня класса, областью уровня экземпляра и локальной областью.

Ответ 6

Чтобы иметь доступ к ним из ваших статических методов, они должны быть статическими переменными-членами, например:

public class MyProgram7 {
  static Scanner scan = new Scanner(System.in);
  static int compareCount = 0;
  static int low = 0;
  static int high = 0;
  static int mid = 0;  
  static int key = 0;  
  static Scanner temp;  
  static int[]list;  
  static String menu, outputString;  
  static int option = 1;  
  static boolean found = false;

  public static void main (String[]args) throws IOException {
  ...

Ответ 7

Теперь вы можете добавлять/использовать экземпляры с помощью метода

public class Myprogram7 {

  Scanner scan;
  int compareCount = 0;
  int low = 0;
  int high = 0;
  int mid = 0;  
  int key = 0;  
  Scanner temp;  
  int[]list;  
  String menu, outputString;  
  int option = 1;  
  boolean found = false;  

  private void readLine() {

  }

  private void findkey() {

  }

  private void printCount() {

  }
  public static void main(String[] args){

    Myprogram7 myprg=new Myprogram7();
    myprg.readLine();
    myprg.findkey();
    myprg.printCount();
  }
}

Ответ 8

Я попытаюсь объяснить вам статическую вещь. Прежде всего статические переменные не принадлежат ни одному конкретному экземпляру класса. Они распознаются с именем класса. Статические методы снова не относятся к какому-либо конкретному экземпляру. Они могут получить доступ только к статическим переменным. Представьте, что вы вызываете MyClass.myMethod(), а myMethod - это статический метод. Если вы используете нестатические переменные внутри метода, как, черт возьми, он знает, какие переменные использовать? Вот почему вы можете использовать из статических методов только статические переменные. Повторяю, они НЕ принадлежат ни одному конкретному экземпляру.

Ответ 9

  • Во-первых, нужно знать разницу между экземпляром класса и самим классом. Класс моделирует определенные свойства и поведение целого в контексте этих свойств. Экземпляр определит конкретные значения для этих свойств.

  • Все, связанное с ключевым словом static, доступно в контексте класса, а не в контексте экземпляра класса

  • Как следствие вышеприведенного

    • переменные внутри метода не могут быть статическими
    • статические поля и методы должны быть вызваны с использованием имени класса, например. MyProgram7.main(...)
  • Время жизни статического поля/метода эквивалентно времени жизни вашего приложения

например. Скажем, автомобиль имеет цвет свойства и демонстрирует поведение "движение". Экземпляром автомобиля будет Красный жук Volkswagen в движении на скорости 25 км/ч.

Теперь статическим свойством автомобиля будет количество колес (4) на дороге, и это применимо ко всем автомобилям.

НТН

Ответ 10

Это бит diff, чтобы объяснить статическое ключевое слово для всех новичков.
Вы узнаете это четко, когда будете больше работать с классами и объектами.

| * | Статический: Статические элементы можно вызвать с именем класса
Если вы наблюдаете в кодах, некоторые функции вызываются непосредственно с именами классов, такими как

NamCls.NamFnc();

System.out.println();

Это потому, что NamFnc и println будут объявлены с использованием ключевого слова static перед ними.

| * | Нестатический: Нестатические элементы можно вызвать с помощью переменной класса Если это не статично, вам нужна переменная класса,
положить точку после переменной класса и затем вызовите функцию.

NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();


Ниже код объясняет вам аккуратно

| * | Статическая и не статическая функция в классе:

public class NamCls
{
    public static void main(String[] args)
    {
        PlsPrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamObjVar.PrnFnc("Tst Txt");
    }

    static void PlsPrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }

    void PrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }
}


| * | Статический и нестатический класс внутри класса:
public class NamCls
{
    public static void main(String[] args)
    {
        NamTicCls NamTicVaj = new NamTicCls();
        NamTicVaj.PrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamNicCls NamNicVar = NamObjVar.new NamNicCls();
        NamNicVar.PrnFnc("Tst Txt");
    }

    static class NamTicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }

    class NamNicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }
}

Ответ 11

Прежде чем вызывать метод экземпляра или переменную экземпляра, ему необходим объект (Instance). Когда переменная экземпляра вызывается из статического метода, компилятор не знает, какому объекту принадлежит эта переменная. Потому что у статических методов нет объекта (всегда только одна копия). Когда вы вызываете переменную экземпляра или методы экземпляра из метода экземпляра, он ссылается на this объект. Это означает, что переменная принадлежит любому созданному объекту, и каждый объект имеет свою собственную копию методов экземпляра и переменных.

Статические переменные помечаются как static а переменные экземпляра не имеют определенного ключевого слова.

Ответ 12

Ответственность за загрузку файлов классов несет ClassLoader. Посмотрите, что происходит, когда мы пишем наши собственные классы.

Пример 1:

class StaticTest {

      static int a;
      int b;
      int c;
}

Теперь мы можем видеть, что класс "StaticTest" имеет 3 поля. Но на самом деле нет существования переменной b, c. Но почему???. ОК, чтобы не видеть. Здесь b, c - переменная экземпляра. Поскольку переменная экземпляра получает память во время создания объекта. Итак, здесь b, c пока не получают никакой памяти. Вот почему нет существования b, c. Итак, существует только существование a. Для ClassLoader у него есть только одна информация о. ClassLoader еще не распознает b, c, потому что объект еще не создан.

Посмотрим еще один пример: Пример 2:

class StaticTest {

      public void display() {
          System.out.println("Static Test");
      }


      public static void main(String []cmd) {

             display();       
      }

}

Теперь, если мы попытаемся скомпилировать этот компилятор кода, вы получите ошибку CE. CE: отображение нестатического метода() не может ссылаться на статический контекст.

Теперь для ClassLoader это выглядит так:

class StaticTest {

      public static void main(String []cmd) {

             display();       
      }

}

В примере 2 ошибка CE заключается в том, что мы вызываем нестатический метод из статического контекста. Таким образом, ClassLoader не может распознавать метод display() во время компиляции. Так возникает ошибка компиляции.

Ответ 13

Статический против нестатического -
РАЗНИЦА, ИСПОЛЬЗОВАНИЕ и ПРИЧИНА, почему нельзя вызывать нестатические методы и/или ссылаться на нестатические поля напрямую (без ссылок на объекты) из static методов -
(*****ВСЕ, ЧТО ТЕБЕ НУЖНО ЗНАТЬ!*****)

Вот вещи, которые вы должны понимать:
(1) разница между static и нестатическими методами и полями
(2) причина, по которой вы не можете вызывать нестатические методы и/или ссылаться на нестатические поля напрямую (без ссылок на объекты) из static методов [с доказательствами] и
(3) когда использовать static/нестатические методы и поля.

1. Разница между static и нестатическими методами и полями

Примечание. Существуют и другие области, в которых static и нестатическая концепция применяется в Java, например, при создании static/нестатических блоков, объявлении static импорта (которое импортирует static члены из классов и позволяет использовать их без ссылки на класс), а также при создании вложенных static/нестатических внутренних классов. Здесь я сужу ответ только для static и экземпляровых (нестатических) методов и полей.

I. static поля:

В Java, если поле объявлено как static, то создается только одна копия этого поля (инициализируется) и распределяется между всеми экземплярами этого класса. Неважно, сколько раз мы инициализируем класс (т.е. создаем экземпляры класса); всегда будет только одна копия static поля, принадлежащего ему. Значение этого static поля будет общим для всего объекта того же или любого другого класса.
Предположим, у нас есть класс Car с несколькими атрибутами (переменные экземпляра). Всякий раз, когда новые объекты инициализируются из этой схемы Car, каждый новый объект будет иметь свою отдельную копию этих переменных экземпляра.
Однако предположим, что мы ищем переменную, которая содержит количество инициализированных объектов Car и распределяется между всеми экземплярами, чтобы они могли обращаться к нему и увеличивать его при создании.
Вот где static переменные входят:

public class Car {
    private String name;
    private String engine;
    public static int numberOfCars;
    public Car(String name, String engine) {
        this.name = name;
        this.engine = engine;
        numberOfCars++;
    }
    // getters and setters
}

Теперь для каждого объекта этого класса, который инициализируется, увеличивается та же копия переменной numberOfCars.

II. static методы:

Подобно static полям, static методы также принадлежат классу, а не объекту, и поэтому их можно вызывать, не создавая объект класса, в котором они находятся. Они предназначены для использования без создания объектов класса. static методы обычно используются для выполнения операции, которая не зависит от создания экземпляра.
Если существует код, который предполагается использовать для всех экземпляров этого класса, напишите этот код в static методе:

...
public static void setNumberOfCars(int numberOfCars) {
    Car.numberOfCars = numberOfCars;
}
...

static методы также широко используются для создания служебных или вспомогательных классов, чтобы их можно было получить без создания нового объекта этих классов.
Достаточно взглянуть на служебные классы Collections или Math из JDK, StringUtils из Apache или CollectionUtils из среды Spring и заметить, что все методы являются static.

III. Экземплярные (нестатические) поля:

В Java нестатические поля объявляются без ключевого слова static. Значение поля для конкретного объекта не передается другим объектам. Предположим, у нас есть класс Car2 с несколькими атрибутами (переменные экземпляра). Всякий раз, когда новые объекты инициализируются из этого проекта Car2, у каждого нового объекта будет отдельная копия этих переменных экземпляра. Примерами нестатических полей в следующей программе являются поля name и engine:

public class Car2 {
    private String name;
    private String engine;
    public static int numberOfCars;
    public Car(String name2, String engine2) {
        name = name2;
        engine = engine2;
        numberOfCars++;
    }
    // getters and setters
}

Теперь для каждого объекта этого класса, который инициализируется, у каждого из них будет отдельная копия этих переменных экземпляра.

Внутривенно Экземплярные (нестатические) методы:

Подобно нестатическим полям, нестатические методы - это методы, которые требуют создания объекта своего класса до его вызова. Чтобы вызвать метод экземпляра, вы должны сначала создать экземпляр (объект) класса, в котором он был определен.
Пример определения метода экземпляра:

...
public void instanceMethod(String name) {
    this.name = name;
}
...

Их можно вызывать в том же классе, в котором они находятся, или из разных классов, определенных либо в том же пакете, либо в других пакетах, в зависимости от спецификатора доступа, предоставленного желаемому методу экземпляра.

НОТА:
Допустимы следующие комбинации экземпляра, static методов и переменных:
- Методы экземпляра могут напрямую обращаться как к методам экземпляра, так и к переменным экземпляра.
- Методы экземпляра также могут напрямую обращаться к static переменным и static методам.
- static методы могут напрямую обращаться ко всем static переменным и другим static методам.
- static методы не могут обращаться к переменным экземпляра и методам экземпляра напрямую; для этого им нужна ссылка на объект. Кроме того, static методы не могут использовать this ключевое слово, так как для this нет экземпляра.

Вот иллюстрация с использованием кода:

Здесь я рассмотрел различные способы вызова/обращения к static/нестатическим членам. Я также включил некоторые советы (в комментариях) в код, а также комментарии к коду, которые приведут к ошибке компиляции, если вы попытаетесь скомпилировать их. Пожалуйста, обратите внимание на эти комментарии с советами.
Примечание. Для краткости код ссылается только на static/нестатические поля внутри static/нестатических методов. Вызов static/нестатических методов из static/нестатических методов не является частью кода, поскольку это похоже на обращение к полям - причина в том, чтобы сохранить код чистым и простым.
Вызов static членов в static методах:
Вызов/обращение к участникам напрямую:

public class StaticTest {
    static int m = 1;
    public static void main(String[] args){
        /*
        Best way to refer to static fields in static 
        methods (if no ambiguity - i.e. field 
        shadowing).
        Best way to call static methods in another 
        static method if both methods are defined 
        in the same class.
        */
        System.out.println(m);
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через имя класса:

public class StaticTest {
    static int m = 1;
    public static void main(String[] args){
        /*
        Best way to refer to static fields in static 
        methods (if there an ambiguity - i.e. field 
        shadowing).
        Best way to call static methods in another 
        static method if one of the methods is 
        defined in a different class.
        */
        System.out.println(StaticTest.m);
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через ссылку на объект:

public class StaticTest {
    static int m = 1;
    public static void main(String[] args){
        /*
        Referring to static fields or calling static 
        methods via object references, whether
        from within static or non-static methods, 
        is completely not advisable. So refrain 
        from it.
        */
        StaticTest st = new StaticTest();
        System.out.println(st.m);
    }
}/* Output:
1
*///:~

Вызов/обращение к участникам через this ключевое слово:

//: !!!ERROR!!!
// Cannot use this in a static context.
public class StaticTest {
    static int m = 1;
    public static void main(String[] args){
        /*
        Cannot use this keyword in static 
        methods!!!
        */
        System.out.println(this.m);
    }
}

Вызов static членов в нестатических методах:
Вызов/обращение к участникам напрямую:

public class StaticTest {
    static int m = 1;
    void nonStatic(){
        /*
        Best way to refer to static fields in 
        non-static methods (if no ambiguity - i.e. 
        field shadowing).
        Best way to call static methods in a non-
        static method.
        */
        System.out.println(m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через имя класса:

public class StaticTest {
    static int m = 1;
    void nonStatic(){
        /*
        Best way to refer to static fields in non-
        static methods (if there an ambiguity - 
        i.e. field shadowing).
        Best way to call static methods in a non-
        static method if one of the methods is 
        defined in a different class.
        */
        System.out.println(StaticTest.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через ссылку на объект:

public class StaticTest {
    static int m = 1;
    void nonStatic(){
        /*
        Referring to static fields or calling static 
        methods via object references, whether
        from within static or non-static methods, 
        is completely not advisable. So refrain 
        from it.
        */
        StaticTest st = new StaticTest();
        System.out.println(st.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов/обращение к участникам через this ключевое слово:

public class StaticTest {
    static int m = 1;
    void nonStatic(){
        /*
        Referring to static fields or calling static 
        methods via this keyword from within 
        non-static methods is completely not 
        advisable. So refrain from it.
        */
        System.out.println(this.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов нестатических членов в нестатических методах:
Вызов/обращение к участникам напрямую:

public class StaticTest {
    int m = 1;
    void nonStatic(){
        /*
        Best way to refer to non-static fields in 
        non-static methods (if no ambiguity - i.e. 
        field shadowing).
        Best way to call non-static methods in 
        another non-static method.
        */
        System.out.println(m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через имя класса:

//: !!!ERROR!!!
// Cannot make a static reference to the 
// non-static field StaticTest.m
public class StaticTest {
    int m = 1;
    void nonStatic(){
        /*
        Cannot call/refer to non-static members 
        using class name (whether from within 
        static or non-static methods)!!!
        */
        System.out.println(StaticTest.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}

Вызов/обращение к членам через ссылку на объект:

public class StaticTest {
    int m = 1;
    void nonStatic(){
        /*
        Best way to refer to non-static fields in 
        non-static methods if and only if you're not 
        referring to the "current execution" of that 
        field but an instance of it (i.e. a copy of it 
        for an object of the class where the field 
        was defined.)
        Best way to call non-static methods in 
        another non-static method if one of the 
        methods is defined in a different class.
        */
        StaticTest st = new StaticTest();
        System.out.println(st.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов/обращение к участникам через this ключевое слово:

public class StaticTest {
    int m = 1;
    void nonStatic(){
        /*
        Best way to refer to non-static fields in 
        non-static methods (if there ambiguity - 
        i.e. field shadowing).
        You dont have to use this keyword when 
        calling non-static methods in another non-
        static method since the compiler does 
        that for you automatically. If you must do 
        so, use this style of method call only when 
        necessary; otherwise you risk confusing 
        the reader/maintainer of your code.
        */
        System.out.println(this.m);
    }
    public static void main(String[] args){
        new StaticTest().nonStatic();
    }
}/* Output:
1
*///:~

Вызов нестатических членов в static методах:
Вызов/обращение к участникам напрямую:

//: !!!ERROR!!!
// Cannot make a static reference to the 
// non-static field m.
public class StaticTest {
    int m = 1;
    public static void main(String[] args){
        /*
        Cannot call/refer to non-static members 
        directly from inside static methods. What 
        this means is that you cannot have 
        access to the "current execution" of non-
        static members from inside static 
        methods. But you can access their (non-
        static members) instances (i.e. copies of 
        them for objects of the class where these 
        members were defined) and that is why 
        you must use objects or their references 
        to do so.
        */
        System.out.println(m);
    }
}

Вызов/обращение к членам через имя класса:

//: !!!ERROR!!!
// Cannot make a static reference to the 
// non-static field StaticTest.m
public class StaticTest {
    int m = 1;
    public static void main(String[] args){
        /*
        Cannot call/refer to non-static members 
        using class name (whether from within 
        static or non-static methods)!!!
        */
        System.out.println(StaticTest.m);
    }
}

Вызов/обращение к членам через ссылку на объект [версия 1]:

public class StaticTest {
    int m = 1;
    public static void main(String[] args){
        /*
        Only way to refer to non-static fields or call 
        non-static methods from within static 
        methods is via objects or their references 
        (or via the static method parameter(s) 
        which is technically object(s) also - for 
        proof, refer to a field using an object 
        reference and pass it as an argument to a 
        static method). You cannot refer to the 
        "current execution" of non-static members 
        (particularly, fields) from a static method. 
        The only thing you can do is refer/call their 
        instances (i.e. copies of non-static 
        members for objects of the class where 
        these members were defined) in static 
        methods.
        */
        StaticTest st = new StaticTest();
        System.out.println(st.m);
    }
}/* Output:
1
*///:~

Вызов/обращение к членам через ссылку на объект [версия 2]:

// Object creation directly in class instead 
// of inside in a method in that class must 
// include the static keyword.
public class StaticTest {
    int m = 1;
    static StaticTest st = new StaticTest();
    public static void main(String[] args){
        /*
        Only way to refer to non-static fields or call 
        non-static methods from within static 
        methods is via objects or their references 
        (or via the static method parameter(s) 
        which is technically object(s) also - for 
        proof, refer to a field using an object 
        reference and pass it as an argument to a 
        static method). You cannot refer to the 
        "current execution" of non-static members 
        (particularly, fields) from a static method. 
        The only thing you can do is refer/call their 
        instances (i.e. copies of non-static 
        members for objects of the class where 
        these members were defined) in static 
        methods.
        */
        System.out.println(st.m);
    }
}/* Output:
1
*///:~

Вызов/обращение к участникам через this ключевое слово:

//: !!!ERROR!!!
// Cannot use this in a static context.
public class StaticTest {
    int m = 1;
    public static void main(String[] args){
        /*
        Cannot use this keyword in static 
        methods!!!
        */
        System.out.println(this.m);
    }
}

2. Причина, по которой вы не можете вызывать нестатические методы и/или ссылаться на нестатические поля напрямую (без ссылок на объекты) из static методов [с доказательствами]

Ключевое слово static указывает, что конкретный член принадлежит самому типу (то есть классу), а не экземпляру этого типа. Это означает, что создается только один экземпляр этого static члена, который является общим для всех экземпляров класса. Когда что-то не является статичным (экземпляр), это означает, что существует экземпляр (копия) этого для каждого экземпляра (объекта) класса. Каждый может измениться независимо. Когда что-то статично, это означает, что для всех экземпляров класса существует только одна его копия, поэтому изменение его из любого местоположения влияет на все остальные.
Поэтому я думаю, что причина, по которой вы не можете напрямую вызывать/ссылаться на нестатические методы и поля внутри static метода, заключается в том, что их значения (static члены) не должны изменяться, а одинаковы независимо от количества экземпляры (объекты) создаваемого класса (и эти статические или неизменяемые значения доступны для всего класса, включая отдельные экземпляры создаваемого класса), вызывающие экземпляры (значения которых относятся к каждому экземпляру класса - это означает, что разные экземпляры имеют свои собственные значения. Следовательно, значения не являются статическими, но изменяются, т.е. каждое из них может изменяться независимо.) напрямую из static методов заставит их (static методы) потерять свою "целостность", делая их значения статичными/неизменными/одинаковыми широкий класс Если static методы могут напрямую обращаться к методам экземпляра и/или полям, это делает их (static методы) логически нестационарными. В этом случае вам может понадобиться/даже необходимо сначала инициализировать объект, прежде чем вы сможете вызвать static метод. (Помните: обычно вам не нужно создавать объект перед вызовом static члена).
Вот доказательства для резервного копирования моего ответа:

I. Эксперименты с кодом:

Предполагая, что есть класс с именем StaticTest с полем экземпляра с именем instanceField и static методом с именем staticMethod. Если возможно, что вы можете вызвать instanceField напрямую (без создания объекта и вызова его по ссылке на объект) из staticMethod, а затем назначить ему значение 5, предполагая, что он имеет тип int. Если вы создаете экземпляр StaticTest и указываете на него ссылку objRef, а затем назначаете 10 для objRef.instanceField, предполагая, что единственный оператор в staticMethod - это System.out.println(instanceField) и если вы вызываете staticMethod, значение instanceField будет последним назначенным значением (т.е. 10 вместо 5) для instanceField экземпляром StaticTest. Если вы создаете другой экземпляр StaticTest и указываете на него ссылку objRef2, а затем назначаете 20 для objRef2.instanceField. Если вы вызываете staticMethod, значением instanceField будет последнее назначенное значение (т. Е. 20 вместо 10 или 5) для instanceField вторым экземпляром StaticTest.
Вот пример кода (Примечание: компиляция следующего кода приведет к ошибке. Он используется только в целях иллюстрации.):

//: StaticTest.java
// Note: this code won't compiler. 
// It just for the purpose of illustration.
public class StaticTest{
    int instanceField = 5;
    static void staticMethod(){
        System.out.println(instanceField); // This will give compile error!!!
    }
    public static void main(String[] args){
        StaticTest objRef = new StaticTest();
        objRef.instanceField = 10;
        staticMethod();
        StaticTest objRef2 = new StaticTest();
        objRef2.instanceField = 20;
        staticMethod();
    }
}

Если приведенный выше код должен был выполняться, вы можете видеть, что каждый раз, когда вызывается staticMethod, даются разные значения, что делает метод потерять его "целостность", делая его статическим/неизменяемым/одинаковым для всего класса.

II. Недоступность this ключевого слова в static методах:

Некоторые люди говорят, что причина, по которой вы не можете получить доступ к членам экземпляра напрямую из static методов, заключается в том, что они (члены экземпляра) не существуют. Фактически, вот цитата из ответа Брайана Ноблауха, который набрал наибольшее количество голосов (более 300 голосов) в StackOverflow:
"Вы не можете вызвать то, что не существует. Поскольку вы еще не создали объект, нестатический метод еще не существует. static метод (по определению) всегда существует".
Если вы также согласны с ним в том, что причина, по которой вы не можете вызывать методы или поля экземпляра напрямую (без предварительного создания объектов и вызова их по ссылке на объект) из static методов, заключается в том, что вы не можете вызвать то, что не существует, Я не думаю, что это настоящая причина. Я сказал это потому, что вы можете вызывать метод экземпляра и/или поле из другого метода экземпляра напрямую, без предварительного создания объектов и вызова их по ссылке на объект.
Если вы говорите, что причина, по которой вы не можете вызывать методы экземпляра или поля из static методов, заключается в том, что вы не можете вызвать то, что не существует, как насчет использования ключевого слова this (например, в случае неоднозначности) для вызова этих поля экземпляра или даже методы?
Помните, что static методы не имеют доступа к ключевому слову this. Для меня тот факт, что вы можете вызывать методы или поля экземпляра, используя ключевое слово this, означает, что эти методы или поля экземпляра уже существуют. Если вы все еще сомневаетесь, помните, что вы можете вызывать static методы или поля с ключевым словом this. Даже если это не очень хорошая практика, и вы получите предупреждающее сообщение, ваша программа все равно будет компилироваться и запускаться. Если вы настаиваете на том, что методы и поля экземпляра не "существуют" (в ваших собственных терминах) без доступа к ним через объект или его ссылку, это означает, что static методы и поля тоже "не существуют", так как вы можете вызвать static методы или поля, использующие ключевое слово this. Кроме того, помните, что вы даже можете вызывать static члены, используя ссылку на объект вместо имени класса (хотя это не очень хорошая практика).

III. "Текущее исполнение":

И что очень важно, также обратите внимание, что вызов/ссылка на методы экземпляра или поля напрямую и вызов/ссылка на них через ссылки на объект - это совершенно разные вещи. Прямой доступ к ним означает доступ к их "текущему выполнению", к которому вы не можете получить доступ из static методов, но доступ к ним через ссылку на объект возможен из static методов, а это означает доступ к их экземплярам (копиям) для каждого объекта (а не их "текущего"). исполнение ").

3. Когда использовать static/нестатические методы и поля

Когда использовать static поля:

  • Когда значение переменной не зависит от объектов.
  • Когда значение должно быть общим для всех объектов.
  • Сделайте поле статическим (например, константой), если вам нужен только один его экземпляр (копия).

Важные моменты, которые следует помнить о static полях:

  • Поскольку static переменные принадлежат классу, к ним можно получить доступ, используя имя класса, и не нужно никаких ссылок на объекты.
  • static переменные могут быть объявлены только на уровне класса.
  • static поля могут быть доступны без инициализации объекта.
  • Хотя мы можем получить доступ к static полям, используя ссылку на объект (например, ford. numberOfCars++, предполагая, что ford является экземпляром класса Car), мы должны воздерживаться от его использования, так как в этом случае становится трудно определить, является ли он переменной экземпляра или классом. переменная; вместо этого мы всегда должны ссылаться на static переменные, используя имя класса (например, в данном случае, Car. numberOfCars++).

Когда использовать static методы:

  • Они в основном используются для доступа к статическим полям поля класса.
  • Для доступа/манипулирования статическими переменными и другими статическими методами, которые не зависят от объектов.
  • static методы широко используются в служебных и вспомогательных классах.
  • Если у вас есть код, который можно использовать для всех экземпляров одного и того же класса, поместите эту часть кода в статический метод.
  • На практике, когда операции на самом деле не требуется объект, метод static утилиты является более подходящим.
  • Сделайте метод static (например, служебный метод), если вам нужен только один его экземпляр (копия).
  • static методы не могут быть переопределены.
  • Хотя static методы могут затруднить написание модульного теста для вашего кода, поскольку вы не можете переопределить их, но они (static методы) занимают меньше памяти, и вызов может быть быстрее.
  • Сделайте ваш метод static если вам не нужен доступ к полям объекта.

Важные моменты, которые следует помнить о static методах:

  • static методы в Java разрешаются во время компиляции. Поскольку переопределение метода является частью полиморфизма времени выполнения, static методы не могут быть переопределены.
  • abstract методы не могут быть статичными.
  • static методы не могут использовать this или super ключевые слова.
  • static методы связаны с классом, в котором они находятся, то есть их можно вызывать даже без создания экземпляра класса, т.е. ClassName.methodName(args).
  • Они предназначены для совместного использования всеми объектами, созданными из одного класса.
  • static методы не могут быть переопределены, но могут быть перегружены, поскольку они разрешаются с помощью static связывания компилятором во время компиляции.

Когда использовать нестатические поля:

  • Когда значение переменной зависит от объектов.
  • Когда значение не должно быть общим для всех объектов.

Важные моменты, которые следует помнить о нестатических полях:

  • Поскольку нестатические переменные принадлежат экземпляру класса, доступ к ним можно получить с помощью ссылки на объект. (Примечание: к ним нельзя получить доступ, используя имя класса.)
  • Нестатические поля объявляются непосредственно внутри класса без ключевого слова static.
  • Нестатические поля не могут быть доступны без инициализации объекта.
  • Каждый отдельный объект, созданный из класса, имеет свою собственную копию полей экземпляра этого класса.

Когда использовать нестатические методы:

  • Для доступа/управления нестатическими полями и другими нестатическими методами, которые зависят от объектов.
  • Нестатические методы могут быть переопределены в подклассе.
  • Сделайте метод нестатичным, если вам требуется его копия для каждого экземпляра (объекта).

Важные моменты, которые следует помнить о нестатических методах:

  • Методы экземпляра принадлежат объекту класса, а не классу, т.е. их можно вызывать после создания объекта (экземпляра класса).
  • Каждый отдельный объект, созданный из класса, имеет свою собственную копию метода (ов) экземпляра этого класса.
  • Нестатические (экземплярные) методы могут быть переопределены, поскольку они разрешаются с использованием динамического связывания во время выполнения.
  • abstract методы не являются статичными.
  • Нестатические методы могут использовать this или super ключевые слова.


    Спасибо!!!


    Фрэнсис Нвокело (императорфин).