Невозможно сделать статическую ссылку на нестатический метод - PullRequest
92 голосов
/ 11 февраля 2011

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

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

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

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

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

Ответы [ 8 ]

136 голосов
/ 11 февраля 2011

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

11 голосов
/ 11 февраля 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.

8 голосов
/ 18 декабря 2011

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

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

т.е.:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

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

myclass.someFunction();

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

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

2 голосов
/ 19 декабря 2015

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

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

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

2 голосов
/ 11 февраля 2011

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

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

2 голосов
/ 11 февраля 2011

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

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

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

0 голосов
/ 20 декабря 2015

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

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

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

  1. Сделать переменную членом-переменной (поле) действия или другого подкласса контекста, удалив статический модификатор и поместив его в тело класса;
  2. Сохраните его статическим и отложите инициализацию до более поздней точки (например, в методе onCreate);
  3. Сделать это локальной переменной в месте фактического использования.
0 голосов
/ 11 февраля 2011

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

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