Невозможно сделать статическую ссылку на нестатический метод

Создание многоязычного приложения на Java. Получение ошибки при вставке значения String из XML файла ресурса R.string:

public static final String TTT =  (String) getText(R.string.TTT);

Это сообщение об ошибке:

Ошибка: не удается сделать статическую ссылку на нестатический метод getText (int) из типа      Контекст

Как это вызвано и как я могу его решить?

Ответ 1

Так как getText() нестатический, вы не можете вызвать его из статического метода.

Чтобы понять, почему, вы должны понимать разницу между ними.

Экземпляры (нестатические) методы работают с объектами определенного типа (класса). Они создаются с помощью нового типа:

SomeClass myObject = new SomeClass();

Чтобы вызвать метод экземпляра, вы вызываете его в экземпляре (myObject):

myObject.getText(...)

Однако статический метод/поле можно называть только только для типа, например: Предыдущее утверждение неверно. Можно также ссылаться на статические поля с ссылкой на объект, например, myObject.staticMethod(), но это обескураживает, поскольку не дает понять, что они являются переменными класса,

... = SomeClass.final

И они не могут работать вместе, поскольку они работают в разных пространствах данных (данные экземпляра и данные класса)

Позвольте мне попытаться объяснить. Рассмотрим этот класс (psuedocode):

class Test {
     string somedata = "99";
     string getText() { return somedata; } 
     static string TTT = "0";
}

Теперь у меня следующий прецедент:

Test item1 = new Test();
 item1.somedata = "200";

 Test item2 = new Test();

 Test.TTT = "1";

Каковы значения?

Ну

in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99

Другими словами, TTT является базой данных, которая разделяется всеми экземплярами типа. Поэтому не имеет смысла говорить

class Test {
         string somedata = "99";
         string getText() { return somedata; } 
  static string TTT = getText(); // error there is is no somedata at this point 
}

Итак, возникает вопрос, почему статический TTT или почему getText() не статичен?

Удалите static, и он должен пройти мимо этой ошибки, но не понимая, что ваш тип делает это только прилипающей штукатуркой до следующей ошибки. Каковы требования getText(), которые требуют от него нестатического?

Ответ 2

Есть несколько хороших ответов уже с объяснениями, почему смесь нестатического метода Context getText() не может использоваться с вашим static final String.

Хороший вопрос: почему вы хотите это сделать? Вы пытаетесь загрузить String из своего ресурса strings и заполнить его значение в поле public static. Я предполагаю, что это так, что некоторые из ваших других классов могут получить к нему доступ? Если это так, нет необходимости делать это. Вместо этого передайте Context в другие классы и вызовите context.getText(R.string.TTT) из них.

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}

И для вызова этого из вашего Activity:

NonActivity.doStuff(this);

Это позволит вам получить доступ к вашему ресурсу String, не используя поле public static.

Ответ 3

для других, которые найдут это в поиске:

Я часто получаю это, когда случайно вызываю функцию, используя имя класса, а не имя объекта. Это обычно происходит, потому что я даю им слишком похожие имена: P

т.е.:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

Это, очевидно, статический метод. (полезно для чего-то) Но то, что я действительно хотел сделать (в большинстве случаев было)

myclass.someFunction();

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

Забавная заметка: переполнение стека подчеркивает синтаксис, чтобы сделать ошибку действительно очевидной.

Ответ 4

Вы можете либо сделать свою переменную не статической

public final String TTT =  (String) getText(R.string.TTT);

или сделать метод getText статическим (если это вообще возможно)

Ответ 5

getText является членом вашей активности, поэтому он должен вызываться, когда существует "this". Ваша статическая переменная инициализируется, когда ваш класс загружается до создания вашей активности.

Поскольку вы хотите, чтобы переменная была инициализирована из строки ресурсов, она не может быть статичной. Если вы хотите, чтобы он был статичным, вы можете инициализировать его с помощью значения String.

Ответ 6

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

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

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

Ответ 7

Этот вопрос не является новым, а существующие ответы дают хороший теоретический фон. Я просто хочу добавить более прагматичный ответ.

getText - это метод абстрактного класса Context, и для его вызова требуется экземпляр этого подкласса (Activity, Service, Application или другое). Проблема состоит в том, что публичные статические конечные переменные инициализируются до создания любого экземпляра контекста.

Существует несколько способов решить эту проблему:

  • Сделать переменную переменной-членом (поле) Activity или другого подкласса Context, удалив статический модификатор и поместив его в тело класса;
  • Держите его статическим и задержите инициализацию до более поздней точки (например, в методе onCreate);
  • Сделать локальную переменную вместо фактического использования.

Ответ 8

Вы не можете использовать нестатический метод для инициализации статической переменной.