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

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

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

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

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

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


person Chen M    schedule 11.02.2011    source источник
comment
Зачем вам нужно, чтобы он был статическим для «многоязычного приложения»? Не совсем понимаю.   -  person xil3    schedule 11.02.2011
comment
Никогда не храните строковые ресурсы в статических элементах данных. Всегда запрашивайте их через getString(), когда они вам нужны. Таким образом, ваше приложение правильно адаптируется к изменению пользователем выбранного языка.   -  person CommonsWare    schedule 11.02.2011
comment
Основы Java :: Учебные курсы   -  person Edward J Beckett    schedule 27.06.2015


Ответы (7)


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

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

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

SomeClass myObject = new SomeClass();

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

myObject.getText(...)

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

... = SomeClass.final

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

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

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() требуют, чтобы он был нестатическим?

person Preet Sangha    schedule 11.02.2011
comment
он статичен, потому что я вызываю его из нескольких файлов в моем проекте. когда я удалил статику, код ошибки исчез, но теперь у меня много ошибок в других файлах, использующих эту переменную. - person Chen M; 11.02.2011
comment
Но это моя точка зрения. Вы должны понимать, когда можно использовать и то, и другое. - person Preet Sangha; 11.02.2011
comment
когда я добавляю строку Constants notifications_values ​​= new Constants (); в мой основной класс активности, он компилируется нормально, но в эмуляторе происходит сбой при запуске этого действия - person Chen M; 11.02.2011

Уже есть несколько хороших ответов с объяснениями, почему смесь нестатического 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.

person dave.c    schedule 11.02.2011
comment
спасибо большое, поменял все файлы по вашей рекомендации. - person Chen M; 12.02.2011
comment
Я пытался сделать это, но для строкового массива и с String a[] = context.getTextArray(R.array.myStringArray);; однако он выдает ошибку The method getTextArray(int) is undefined for the type Context - почему он должен быть undefined, если он работает с getText? - person auspicious99; 06.08.2014
comment
@ auspicious99 просто потому, что Context не имеет метода с именем getTextArray, но есть getText. Возможно, вы думаете о Resources, в котором есть getTextArray - person dave.c; 07.08.2014

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

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

ie:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

Очевидно, что это статический метод. (кое-что хорошо) Но то, что я действительно хотел сделать (в большинстве случаев было)

myclass.someFunction();

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

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

person SpiRail    schedule 18.12.2011
comment
Разве в вашей среде IDE это тоже не подчеркивается? Думаю, вы можете настроить его так :) - person Matthias Meid; 18.12.2011
comment
это сэкономило мне несколько часов моего времени, СПАСИБО !! - person Daria M; 25.11.2020

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

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

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

person Kellindil    schedule 11.02.2011

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

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

person Robby Pond    schedule 11.02.2011

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

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

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

person Krishna    schedule 19.12.2015

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

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

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

  1. Сделайте переменную переменной-членом (полем) Activity или другого подкласса Context, удалив модификатор static и поместив его в тело класса;
  2. Сохраните его статическим и отложите инициализацию до более поздней стадии (например, в методе onCreate);
  3. Сделайте его локальной переменной вместо фактического использования.
person dev.bmax    schedule 20.12.2015