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

时间:2011-02-11 12:49:13

标签: java compiler-errors static-methods

使用Java构建多语言应用程序。从R.string资源XML文件插入字符串值时出错:

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

这是错误消息:

  

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

这是如何引起的?如何解决?

8 个答案:

答案 0 :(得分:136)

由于getText()是非静态的,因此无法通过静态方法调用它。

要了解原因,您必须了解两者之间的区别。

实例(非静态)方法适用于特定类型(类)的对象。这些是用这样的新东西创建的:

SomeClass myObject = new SomeClass();

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

myObject.getText(...)

但是静态方法/字段可以直接在类型上被称为 ,比如说: 之前的陈述不正确。 One can also refer to static fields with an object reference like 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()要求它是非静态的要求是什么?

答案 1 :(得分:11)

已经有一些很好的答案,解释了为什么非静态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资源。

答案 2 :(得分:8)

其他在搜索中找到此内容的人:

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

即:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

这显然是一种静态方法。 (适合某些人) 但我真正想做的事情(在大多数情况下是)

myclass.someFunction();

这是一个如此愚蠢的错误,但是每隔几个月,我浪费了大约30分钟来处理“MyClass”定义中的变量,以便弄清楚我真正做错了什么,这只是一个错字。

有趣的是:堆栈溢出突出了语法,使错误在这里显而易见。

答案 3 :(得分:2)

您可以使变量非静态

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

或将“getText”方法设为静态(如果可能的话)

答案 4 :(得分:2)

getText是您的Activity的成员,因此必须在" this"存在。在创建Activity之前加载类时,会初始化静态变量。

由于您希望从资源字符串初始化变量,因此它不能是静态的。如果您希望它是静态的,可以使用String值初始化它。

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:0)

这个问题并不新鲜,现有的答案给出了一些很好的理论背景。我只想添加一个更实用的答案。

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

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

  1. 通过删除static修饰符并将其放在类主体中,使变量成为Activity或Context的其他子类的成员变量(字段);
  2. 保持静态并将初始化延迟到稍后的点(例如在onCreate方法中);
  3. 在实际使用位置将其设为局部变量。

答案 7 :(得分:-1)

您不能使用非静态方法初始化静态变量。