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(int)进行静态引用 上下文 这是如何导致的,我如何解决它?因为getText()是非静态的,所以不能从静态方法调用它 要理解原因,你必须理解两者之间的区别 实例(非静态)方法处理特定类型(类)的对象。这些都是用新的创建的

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

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

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

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

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

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

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

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

但是,静态方法/字段只能直接在类型上调用,如下所示: 前面的陈述是不正确的
myObject.staticMethod()
但不鼓励这样做,因为它没有明确说明它们是类变量

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

让我试着解释一下。考虑这个类(pSuEDoCODE):

现在我有了以下用例:

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是活动的成员,所以必须在“this”存在时调用它。在创建活动之前加载类时,将初始化静态变量


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

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

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

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}
要从您的
活动中调用此选项,请执行以下操作:

NonActivity.doStuff(this);

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

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

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

即:

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

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


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

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

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


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

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

getText是上下文抽象类的方法,为了调用它,需要它的子类(活动、服务、应用程序或其他)的实例。问题是,公共静态final变量在创建上下文的任何实例之前被初始化

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

  • 通过移除静态修饰符并将其放置在类主体中,使该变量成为活动或上下文的其他子类的成员变量(字段)
  • 保持静态,并将初始化延迟到稍后的时间点(例如,在onCreate方法中)
  • 在实际使用时将其作为局部变量

  • 对于“多语言应用程序”,为什么需要它是静态的?不太明白。永远不要在静态数据成员中存储字符串资源。需要时,始终通过
    getString()
    请求它们。这样,您的应用程序可以根据用户更改其选择的语言进行适当调整。它是静态的,因为我从项目中的多个文件中调用它。当我删除“static”时,错误代码消失了,但是现在我在使用这个变量的其他文件中有很多错误。但这就是我的观点。您需要了解何时可以使用这两个选项。当我在主活动类中添加行“Constants notifications_values=new Constants();时,它可以编译,但在emulator中,当此活动运行时它会崩溃非常感谢您,我根据您的建议更改了所有文件
    class Test {
             string somedata = "99";
             string getText() { return somedata; } 
      static string TTT = getText(); // error there is is no somedata at this point 
    }
    
    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();