无法对非静态方法进行静态引用

用Java构build多语言应用程序 从R.string资源XML文件插入String值时出现错误:

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

这是错误信息:

错误:无法从types上下文中对非静态方法getText(int)进行静态引用

这是如何造成的,我该如何解决?

由于getText()是非静态的,所以不能从静态方法调用它。

要理解为什么,你必须了解两者的区别。

实例(非静态)方法适用于特定types的对象(类)。 这些是用这样的新build立的:

 SomeClass myObject = new SomeClass(); 

要调用实例方法,可以在实例( myObject )上调用它:

 myObject.getText(...) 

然而,一个静态的方法/字段只能在types上直接调用,就像这样: 前面的语句是不正确的。 我们也可以使用像 myObject.staticMethod()这样的对象引用来引用静态字段,但不鼓励这样做,因为它没有明确指出它们是类variables。

 ... = 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是所有types实例共享的数据。 所以说没有意义

 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 ,它应该通过这个错误 – 但不知道你的types是什么,它只是一个粘贴石膏,直到下一个错误。 getText()需要非静态的要求是什么?

已经有一些很好的答案,解释了为什么非静态的Context方法getText()不能用于你的static final String

一个很好的问题是:你为什么要这样做? 您正试图从您的strings资源中加载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字段。

对于在search中find它的其他人:

当我不小心使用类名称而不是对象名称调用函数时,我经常得到这个。 这通常发生,因为我给他们太类似的名字:P

即:

 MyClass myclass = new MyClass(); // then later MyClass.someFunction(); 

这显然是一个静态的方法。 (对一些事情有好处)但是我真正想做的事情(在大多数情况下)

 myclass.someFunction(); 

这是一个愚蠢的错误,但每隔几个月,我就用“MyClass”的定义浪费了大约30分钟的时间,以弄清楚什么是错误的,只是错误。

滑稽注意:堆栈溢出突出显示语法,使错误在这里显而易见。

你可以让你的variables不是静态的

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

或者使“getText”方法是静态的(如果可能的话)

getText是你的Activity的成员,所以当“this”存在时必须调用它。 你的静态variables在你的类被加载之前被初始化,然后你的Activity被创build。

既然你想要从一个资源string初始化variables,那么它不能是静态的。 如果你希望它是静态的,你可以用String值初始化它。

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

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

现在来到你的问题,当你使用new()运算符时,我们将为每个对象创build每个非静态字段的副本,但静态字段并不是这样。 这就是为什么如果你从非静态方法引用一个静态variables,它会给编译时错误。

这个问题不是新的,现有的答案给了一些很好的理论背景。 我只想补充一个更实用的答案。

getText是Context抽象类的一种方法,为了调用它,需要一个子类的实例(Activity,Service,Application或其他)。 问题是公共静态最终variables是在任何Context创build之前被初始化的。

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

  1. 通过移除静态修饰符并将其放置在类体中,使variables成为Activity或其他Context的其他子类的成员variables(字段);
  2. 保持静态并延迟初始化(例如在onCreate方法中);
  3. 在实际使用的地方把它变成一个局部variables。

您不能使用非静态方法来初始化静态variables。