Cannot make a static reference to the non-static method

Building a multi-language application in Java. Getting an error when inserting String value from R.string resource XML file:

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

This is the error message:

Error: Cannot make a static reference to the non-static method getText(int) from the type Context

How is this caused and how can I solve it?

460375 次浏览

因为 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
}

So the question is why is TTT static or why is getText() not static?

Remove the static and it should get past this error - but without understanding what your type does it's only a sticking plaster till the next error. What are the requirements of getText() that require it to be non-static?

您可以将变量设置为非静态的

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

or make the "getText" method static (if at all possible)

GetText 是 Activity 的一个成员,因此当“ this”存在时必须调用它。静态变量是在创建 Activity 之前加载类时初始化的。

因为您希望从 Resource 字符串初始化变量,所以它不能是静态的。如果希望它是静态的,可以使用 String 值对其进行初始化。

有一些很好的答案已经与解释为什么非静态 Context方法 getText()的混合物不能与您的 static final String使用。

一个很好的问题是: 你为什么要这么做?您正试图从 strings资源加载 String,并将其值填充到 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字段。

对于其他在搜索中发现这一点的人来说:

当我不小心使用类名而不是对象名调用函数时,我经常遇到这种情况。这种情况通常发生,因为我给它们起了太相似的名字: P

即:

MyClass myclass = new MyClass();


// then later


MyClass.someFunction();

这显然是一个静态方法 但我真正想做的(在大多数情况下)

myclass.someFunction();

这是一个非常愚蠢的错误,但是每隔几个月,我会花大约30分钟的时间在“ MyClass”的定义中修改 vars 来弄清楚我到底做错了什么,实际上,这只是一个打字错误。

有趣的提示: 堆栈溢出突出显示了语法,这里的错误非常明显。

不能从非静态方法引用静态变量。 为了理解这一点,您需要理解静态和非静态之间的区别。

静态变量是类变量,它们属于类,只有一个实例,只在第一个实例创建时创建。 每次创建类的对象时,都会初始化非静态变量。

现在回到您的问题,当您使用 new ()操作符时,我们将为每个对象创建每个非静态文件的副本,但静态字段不是这种情况。这就是为什么在从非静态方法引用静态变量时会出现编译时错误的原因。

This question is not new and existing answers give some good theoretical background. I just want to add a more pragmatic answer.

GetText 是 Context 抽象类的一个方法,为了调用它,需要其子类(Activity、 Service、 Application 或其他)的一个实例。问题是,在创建 Context 的任何实例之前,都会初始化公共静态 final 变量。

有几种方法可以解决这个问题:

  1. 通过移除静态修饰符并将其置于类主体中,使变量成为 Activity 或其他 Context 子类的成员变量(字段) ;
  2. 保持静态并将初始化延迟到稍后的时间点(例如 onCreate 方法) ;
  3. Make it a local variable in the place of actual usage.

是的,你可以把非静态方法调用成静态方法,因为我们首先要记住,我们可以创建一个类,我们可以很容易地把非静态方法调用成静态方法