На нестатическую переменную нельзя ссылаться из статического контекста - PullRequest
255 голосов
/ 01 апреля 2010

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

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);
                           ^

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

Ответы [ 12 ]

258 голосов
/ 01 апреля 2010

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

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

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

В ОО-мире вы определяете класс, а внутри класса вы определяете поле типа 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() создается с классом, а не с экземпляром, он может это сделать), а затем вызывает метод экземпляра (run()).

73 голосов
/ 01 апреля 2010

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

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

class Programm {

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

    public void start() {
        // can now access non-static fields
    }
}
40 голосов
/ 16 января 2015

Ключевое слово 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, не могут использоваться, пока экземпляр класса не будет создан как объект в * 1038. * метод. После создания объекта вы можете использовать переменные и методы объекта. Попытка использовать переменные и методы класса, у которых нет модификатора 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
    }
}
11 голосов
/ 24 июля 2013

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

11 голосов
/ 18 июля 2011

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

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

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

8 голосов
/ 01 апреля 2010

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

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 голосов
/ 24 сентября 2013

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

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();
  }
}
4 голосов
/ 01 апреля 2010

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

2 голосов
/ 25 мая 2018

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

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

2 голосов
/ 01 апреля 2010
  • Прежде всего нужно знать разницу между экземпляром класса и самим классом. Класс моделирует определенные свойства и поведение целого в контексте этих свойств. Экземпляр будет определять конкретные значения для этих свойств.

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

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

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

например. Скажем, автомобиль имеет свойство color и демонстрирует поведение «движение». Экземпляр этого автомобиля - красный Volkswagen Beetle, движущийся со скоростью 25 км / ч.

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

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...