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

Java 无法对非静态方法进行静态引用,java,compiler-errors,static-methods,Java,Compiler Errors,Static Methods,用Java构建多语言应用程序。从R.String资源XML文件插入字符串值时出错: public static final String TTT = (String) getText(R.string.TTT); 这是错误消息: 错误:无法对从类型中删除的非静态方法进行静态引用 上下文 这是如何导致的,我如何解决它?因为getText是非静态的,所以不能从静态方法调用它 要理解原因,你必须理解两者之间的区别 实例非静态方法处理类中特定类型的对象。这些都是用新的创建的,如下所示: SomeCl

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

public static final String TTT =  (String) getText(R.string.TTT);
这是错误消息:

错误:无法对从类型中删除的非静态方法进行静态引用 上下文

这是如何导致的,我如何解决它?

因为getText是非静态的,所以不能从静态方法调用它

要理解原因,你必须理解两者之间的区别

实例非静态方法处理类中特定类型的对象。这些都是用新的创建的,如下所示:

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

但是,只能直接对类型调用静态方法/字段,例如: 前面的陈述是不正确的。但是不鼓励这样做,因为它没有明确说明它们是类变量

这两者不能一起工作,因为它们操作不同的数据空间实例数据和类数据

让我试着解释一下。考虑这个类的伪代码:

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";
价值观是什么

换句话说,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不是静态的


去掉静电,它应该会克服这个错误——但是如果不了解你的类型,它在下一个错误之前只是一个橡皮膏。getText的哪些要求是非静态的?

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

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

或者,若getText是活动的一个成员,则尽可能使getText方法成为静态的,所以必须在该方法存在时调用它。在创建活动之前加载类时,将初始化静态变量


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

已经有一些很好的答案,解释了为什么非静态上下文方法getText不能与静态最终字符串混合使用

一个好问题是:你为什么要这样做?您正试图从字符串资源加载字符串,并将其值填充到公共静态字段中。我假设这是为了让其他一些类可以访问它?如果是这样,就没有必要这样做。相反,将上下文传递到其他类中,并从它们内部调用Context.gettext.string.TTT

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}
从您的活动中调用:


这将允许您访问字符串资源,而无需使用公共静态字段。

对于在搜索中找到此字段的其他人:

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

即:

这显然是一种静态方法。有好处 但在大多数情况下,我真正想做的是

myclass.someFunction();
这是一个愚蠢的错误,但每隔几个月,我就会浪费大约30分钟在MyClass定义中处理变量,以找出我做错了什么,而实际上,这只是一个打字错误


有趣的是:堆栈溢出突出显示了使错误变得非常明显的语法

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

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


现在来回答您的问题,当您使用新操作符时,我们将为每个对象创建每个非静态字段的副本,但静态字段的情况并非如此。这就是为什么从非静态方法引用静态变量时会出现编译时错误。

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

getText是上下文抽象类的方法,为了调用它,需要其子类Activity、Service、Application或其他的实例。问题是,公共静态final变量在创建上下文的任何实例之前被初始化

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

通过移除静态修饰符并将其放置在类主体中,使变量成为活动或上下文的其他子类的成员变量字段; 保持静态,并将初始化延迟到稍后的时间点,例如在onCreate方法中; 在实际使用时将其作为局部变量。
对于“多语言应用程序”,为什么需要它是静态的?不太明白。永远不要存储字符串资源
静态数据成员中的。需要时,始终通过getString请求它们。这样,您的应用程序可以根据用户更改其选择的语言进行适当调整。它是静态的,因为我从项目中的多个文件中调用它。当我删除静态变量时,错误代码消失了,但是现在我在使用这个变量的其他文件中有很多错误。但这就是我的观点。您需要了解何时可以使用这两个;对于我的主activity类,它可以编译,但在emulator中,当此活动运行时它会崩溃非常感谢,我根据您的建议更改了所有文件;但是,它给了我一个错误,方法getTextArrayint对于类型上下文是未定义的-为什么它是未定义的,而它与getText一起工作?原因很简单,因为a没有名为getTextArray的方法,但有getText。也许您正在考虑哪些具有getTextArrayDoesn,而您的IDE不也突出显示了这一点吗?我想你可以配置它这样做:这节省了我几个小时的时间,谢谢!!
public final String TTT =  (String) getText(R.string.TTT);
public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}
NonActivity.doStuff(this);
MyClass myclass = new MyClass();

// then later

MyClass.someFunction();
myclass.someFunction();