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

js81xvg6  于 2021-08-20  发布在  Java
关注(0)|答案(11)|浏览(468)

我编写了以下测试代码:

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

但它给出了以下错误:

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

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

kb5ga3dv

kb5ga3dv1#

您必须了解类和该类示例之间的区别。如果你在街上看到一辆车,即使你看不到它的型号,你也会马上知道它是一辆车。这是因为您将看到的内容与“汽车”类进行比较。该类包含与所有汽车相似的。把它看作一个模板或一个想法。
同时,您看到的汽车是“car”类的一个示例,因为它具有您所期望的所有属性:有人驾驶它,它有一个发动机和车轮。
所以这个类说“所有的汽车都有一种颜色”,而这个示例说“这个特定的汽车是红色的”。
在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
}

新的 main() 方法创建它所包含的类的示例(听起来很奇怪,但因为 main() 是用类而不是示例创建的,它可以这样做),然后调用示例方法( run() ).

rta7y2nd

rta7y2nd2#

静态字段和方法连接到类本身,而不是它的示例。如果你有课 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
    }
}
cygmwpex

cygmwpex3#

这个 static 关键字修改类中方法或变量的生命周期。A. static 方法或变量是在加载类时创建的。未声明为的方法或变量 static 仅当类被示例化为对象时(例如通过使用 new 操作人员
广义而言,类的生命周期是:
该类的源代码创建了一个模板、模式或戳记,然后可以用来
使用 new 运算符使用该类将该类的示例作为实际对象,然后在使用该对象时
销毁对象,回收其所持有的资源,如垃圾回收期间的内存。
为了获得应用程序的初始入口点,java采用了一种约定,即java程序必须有一个类,该类包含一个具有约定名称或特殊名称的方法。这种特殊方法称为 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() 方法。创建对象后,可以使用对象的变量和方法。试图使用类中没有 static java编译器在编译时捕获未经过类对象的修饰符,并将其标记为错误。

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
    }
}
clj7thdc

clj7thdc4#

让我们先分析一下你的程序。。在程序中,第一种方法是 main() ,记住这是静态方法。。。然后为该方法声明局部变量(comparecount、low、high等)。此变量的作用域仅为声明的方法,而不管它是静态方法还是非静态方法。所以你不能在这个方法之外使用这些变量。这是你犯的基本错误。
然后我们来讨论下一点。你说过静电会杀了你(它可能会杀死你,但它只会给你的程序带来生命!!)首先,你必须了解基本情况静态方法只调用静态方法,并且只使用静态变量静态变量或静态方法不依赖于该类的任何示例(i、 e.如果您更改静态变量的任何状态,它将反映在类的所有对象中)*因此您将其称为类变量或类方法。还有更多关于“静态”关键字的内容。我希望你现在明白了。首先更改变量的范围并将其声明为静态(以便能够在静态方法中使用它)。
给你的建议是:你误解了变量和静态功能的范围。弄清楚这一点。

rekjcdws

rekjcdws5#

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

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 {
  ...
dl5txlt9

dl5txlt96#

最基本的是静态变量或静态方法在类级别。类级别的变量或方法在示例级别的方法或变量之前被加载。显然,没有加载的东西不能被使用。因此,java编译器不允许在运行时处理的问题在编译时解决。这就是为什么它会给你错误,非静态的东西不能从静态上下文中引用。您只需要了解类级范围、示例级范围和本地范围。

55ooxyrt

55ooxyrt7#

现在,您可以在方法中添加/使用具有的示例

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();
  }
}
5fjcxozz

5fjcxozz8#

我会尽力向你解释静态的事情。首先,静态变量不属于该类的任何特定示例。它们通过类的名称识别。静态方法不再属于任何特定示例。它们只能访问静态变量。假设您调用myclass.mymethod(),mymethod是一个静态方法。如果在方法中使用非静态变量,它究竟如何知道使用哪些变量?这就是为什么只能从静态方法使用静态变量。我再次重申,它们不属于任何特定情况。

9gm1akwq

9gm1akwq9#

首先要知道类的示例和类本身之间的区别。类对某些属性以及这些属性上下文中的整体行为进行建模。示例将为这些属性定义特定值。
任何绑定到static关键字的内容都可以在类的上下文中使用,而不是在类示例的上下文中使用
作为上述情况的必然结果
方法中的变量不能是静态的
静态字段和方法必须使用类名调用,例如myprogram7.main(…)
静态字段/方法的生存期与应用程序的生存期相等
e、 比如说,汽车具有属性颜色,并表现出“运动”行为。这辆车的一个例子就是一辆时速25公里的红色大众甲壳虫。
现在汽车的静态特性是道路上的车轮数(4),这将适用于所有汽车。

u0sqgete

u0sqgete10#

在调用示例方法或示例变量之前,它需要一个对象(示例)。当从静态方法调用示例变量时,编译器不知道该变量属于哪个对象。因为静态方法没有对象(始终只有一个副本)。当您从示例方法调用示例变量或示例方法时,它引用 this 对象这意味着变量属于创建的任何对象,每个对象都有自己的示例方法和变量副本。
静态变量标记为 static 示例变量没有特定的关键字。

x6492ojm

x6492ojm11#

类加载器负责加载类文件。让我们看看当我们编写自己的类时会发生什么。
例1:

class StaticTest {

      static int a;
      int b;
      int c;
}

现在我们可以看到“statictest”类有3个字段。但是实际上不存在b,c成员变量。但是为什么???。好吧,让我看看。这里b,c是示例变量。因为示例变量在对象创建时获得内存。所以这里b,c还没有得到任何内存。这就是为什么不存在b,c。所以只有a的存在。对于类加载器,它只有一个关于a的信息。类加载器还不能识别b,c,因为它是obj

相关问题