无法从静态上下文引用非静态变量

Gre*_*reg 272 java variables compiler-errors non-static

我写了这个测试代码:

class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}
Run Code Online (Sandbox Code Playgroud)

但它给出了以下错误:

Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^
Run Code Online (Sandbox Code Playgroud)

如何让我的方法识别我的类变量?

Aar*_*lla 277

您必须了解类和该类的实例之间的区别.如果你在街上看到一辆汽车,即使你看不到哪种型号或类型,你也会立即知道它是一辆汽车.这是因为您将所看到的与"汽车" 进行比较.该类包含类似于所有汽车的类.将其视为模板或想法.

与此同时,您看到的汽车是"汽车"级别的一个实例,因为它具有您期望的所有属性:有人驾驶它,它有发动机,车轮.

因此课程上说"所有车都有颜色",实例说"这辆特定的车是红色的".

在OO世界中,您定义类并在类中定义一个类型的字段Color.实例化类时(创建特定实例时),将为颜色保留内存,您可以为此特定实例指定颜色.由于这些属性是特定的,因此它们是非静态的.

静态字段和方法与所有实例共享.它们用于特定于类的值,而不是特定的实例.对于方法,这通常是全局辅助方法(如Integer.parseInt()).对于字段,它通常是常量(例如汽车类型,即您拥有有限集合且不经常更改的东西).

要解决您的问题,您需要实例化类的实例(创建一个对象),以便运行时可以为实例保留内存(否则,不同的实例会相互覆盖您不想要的内容).

在您的情况下,请尝试此代码作为起始块:

public static void main (String[] args)
{
    try
    {
        MyProgram7 obj = new MyProgram7 ();
        obj.run (args);
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
}

// instance variables here

public void run (String[] args) throws Exception
{
    // put your code here
}
Run Code Online (Sandbox Code Playgroud)

main()方法创建它包含的类的实例(听起来很奇怪,但由于main()是使用类而不是实例创建的,因此它可以执行此操作),然后调用实例方法(run()).

  • 我现在正在向我们的新同事解释这一点 - 感谢您的精彩解释。这应该是接受者的回答。 (3认同)
  • 这太烦人了。如果你开始使用java并尝试创建一个java文件,它要求你将主类设置为静态,如果你删除静态那么java将无法运行。如果保持静态,则会出现上述错误。然后,当程序中的任何变量都没有出现上述错误时,你在谷歌上搜索帮助,你会得到十几个人解释java内部结构的优点,而不是解决问题。 (3认同)
  • 那么特斯拉汽车呢? (2认同)

Mne*_*nth 80

静态字段和方法连接到类本身而不是其实例.如果你有一个类A,一个"正常"的方法b,和静态方法c,你让一个实例a类的A,则调用A.c()a.b()有效.方法c()不知道连接了哪个实例,因此不能使用非静态字段.

您的解决方案是让您的字段静态或您的方法是非静态的.那么你的主要看起来像这样:

class Programm {

    public static void main(String[] args) {
        Programm programm = new Programm();
        programm.start();
    }

    public void start() {
        // can now access non-static fields
    }
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*ers 44

static关键字修改类内的方法或可变的生命周期.甲static在一类被加载时被创建方法或可变的.未声明为的方法或变量static仅在将类实例化为对象时创建,例如通过使用new运算符.

从广义上讲,课程的生命周期是:

  1. 写入类的源代码,创建一个模板或模式或图章,然后可以使用它
  2. new使用该类创建一个对象,将该类的实例作为实际对象,然后在完成该对象时
  3. 在垃圾回收期间销毁回收它所持有的资源的对象,例如内存.

为了获得应用程序的初始入口点,Java采用了Java程序必须具有包含具有约定或特殊名称的方法的类的约定.调用这种特殊方法main().由于该方法必须存在,无论包含main方法的类是否已经实例化,因此main()必须使用static修饰符声明该方法,以便一旦加载该类,该main()方法就可用.

结果是当您通过命令行启动Java应用程序时,例如java helloworld一系列操作发生.首先启动并初始化Java虚拟机.接下来,将包含已编译Java代码的helloworld.class文件加载到Java虚拟机中.然后Java虚拟机在helloworld被调用的类中查找方法main(String [] args).static即使该类实际上没有被实例化为对象,该方法也必须存在.Java虚拟机不会通过从类创建对象来创建类的实例.它只是加载类并开始执行该main()方法.

因此,您需要创建类的实例作为对象,然后您可以访问尚未使用static修饰符声明的类的方法和变量.一旦您的Java程序开始使用该main()函数,您就可以使用具有修饰符的任何变量或方法,static因为它们作为要加载的类的一部分存在.

但是,在类的实例被创建为方法中的对象之前,不能使用main()那些不具有static修饰符的方法之外的类的变量和main()方法.创建对象后,您可以使用对象的变量和方法.staticJava编译器在编译时捕获尝试使用没有修饰符但没有经过类对象的类的变量和方法,并将其标记为错误.

import java.io.*;

class HelloWorld {
    int myInt;      // this is a class variable that is unique to each object
    static int myInt2;  // this is a class variable shared by all objects of this class

    static void main (String [] args) {
        // this is the main entry point for this Java application
        System.out.println ("Hello, World\n");
        myInt2 = 14;    // able to access the static int
        HelloWorld myWorld = new HelloWorld();
        myWorld.myInt = 32;   // able to access non-static through an object
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

让我们先分析你的程序..在你的程序中,你的第一个方法是main(),并记住它是静态方法......然后你声明该方法的局部变量(compareCount,low,high等等).此变量的范围仅是声明的方法,无论它是静态还是非静态方法.所以你不能在那个方法之外使用那些变量.这是你犯的基本错误.

然后我们来到下一点.你告诉静电正在杀了你.(它可能会杀死你,但它只会给你的程序带来生命!!)首先,你必须了解基本的东西.*静态方法只调用静态方法,只使用静态变量.*静态变量或静态方法不依赖于该类的任何实例.(即,如果更改静态变量的任何状态,它将反映在类的所有对象中)*因此,您将其称为类变量或类方法.关于"静态"关键字还有很多.我希望你现在明白了.首先更改变量的范围并将其声明为静态(以便能够在静态方法中使用它).

对你的建议是:你误解了变量范围和静态功能的想法.清楚地了解这一点.


小智 11

最基本的东西是静态变量或静态方法是在类级别.在实例级方法或变量之前加载类级变量或方法.显然,不能使用未加载的东西.所以java编译器不允许在运行时处理事情在编译时解析.这就是为什么它给你错误非静态的东西不能从静态上下文中引用.您只需要阅读有关类级别范围,实例级别范围和本地范围的信息.


Nic*_*ore 8

为了能够从静态方法访问它们,它们需要是静态成员变量,如下所示:

public class MyProgram7 {
  static Scanner scan = new Scanner(System.in);
  static int compareCount = 0;
  static int low = 0;
  static int high = 0;
  static int mid = 0;  
  static int key = 0;  
  static Scanner temp;  
  static int[]list;  
  static String menu, outputString;  
  static int option = 1;  
  static boolean found = false;

  public static void main (String[]args) throws IOException {
  ...
Run Code Online (Sandbox Code Playgroud)


Sai*_*ate 8

现在,您可以在方法中添加/使用实例

public class Myprogram7 {

  Scanner scan;
  int compareCount = 0;
  int low = 0;
  int high = 0;
  int mid = 0;  
  int key = 0;  
  Scanner temp;  
  int[]list;  
  String menu, outputString;  
  int option = 1;  
  boolean found = false;  

  private void readLine() {

  }

  private void findkey() {

  }

  private void printCount() {

  }
  public static void main(String[] args){

    Myprogram7 myprg=new Myprogram7();
    myprg.readLine();
    myprg.findkey();
    myprg.printCount();
  }
}
Run Code Online (Sandbox Code Playgroud)