无法对非静态方法进行静态引用
用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之前被初始化的。
有几种方法可以解决这个问题:
- 通过移除静态修饰符并将其放置在类体中,使variables成为Activity或其他Context的其他子类的成员variables(字段);
- 保持静态并延迟初始化(例如在onCreate方法中);
- 在实际使用的地方把它变成一个局部variables。
您不能使用非静态方法来初始化静态variables。