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

我写了这个测试代码:

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); ^ 

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

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

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

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

在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() )。

静态字段和方法连接到类本身而不是其实例。 如果你有一个A类,一个’普通’方法b和一个静态方法c ,并且你创建了a A类实例,那么对Ac()ab()的调用是有效的。 方法c()不知道连接了哪个实例,因此它不能使用非静态字段。

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

 class Programm { public static void main(String[] args){ Programm programm = new Programm(); programm.start(); } public void start(){ // can now access non-static fields } } 

static关键字修改类中方法或变量的生命周期。 在加载类时创建static方法或变量。 仅当将类实例化为对象(例如,使用new运算符)时,才会创建未声明为static的方法或变量。

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

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

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

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

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

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

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

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

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

对你的建议是:你误解了变量范围和静态function的想法。 对此有清楚的认识。

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

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

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

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

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

我会尝试向你解释静态的东西。 首先,静态变量不属于该类的任何特定实例。 他们被认可为class级的名称。 静态方法再次不属于任何特定实例。 他们只能访问静态变量。 想象一下,你调用MyClass.myMethod()和myMethod是一个静态方法。 如果你在方法中使用非静态变量,地球上究竟会知道使用哪些变量? 这就是为什么你只能使用静态方法静态变量。 我再说一遍,他们不属于任何特定的实例。

  • 首先要知道类的实例和类本身之间的区别。 类对某些属性进行建模,并在这些属性的上下文中对整体的行为进行建模。 实例将为这些属性定义特定值。

  • 绑定到static关键字的任何内容都可以在类的上下文中使用,而不是在类的实例的上下文中

  • 作为上述的必然结果

    1. 方法中的变量不能是静态的
    2. 必须使用类名调用静态字段和方法,例如MyProgram7.main(…)
  • 静态字段/方法的生命周期等于应用程序的生命周期

比如说,汽车具有属性颜色,并表现出行为’运动’。 这辆汽车的一个例子是红色大众甲壳虫以25公里/小时的速度运动。

现在汽车的静态特性将是道路上的车轮(4)的数量,这适用于所有汽车。

HTH

对于所有初学者来说,这是一个有点不同的解释静态关键词。
当您使用Classes和Objects更多地工作时,您将清楚地了解它。

| * | 静态:可以使用类名调用静态项
如果你在代码中观察,有些函数是直接用类名来调用的

 NamCls.NamFnc(); System.out.println(); 

这是因为NamFnc和println将在它们之前使用关键字static声明。

| * | 非静态:可以使用类变量调用非静态项
如果它不是静态的,你需要一个类的变量,
在类变量之后放点
然后调用函数。

 NamCls NamObjVar = new NamCls(); NamObjVar.NamFnc(); 

下面的代码整齐地解释了你

| * | 类中的静态和非静态函数:

 public class NamCls { public static void main(String[] args) { PlsPrnFnc("Tst Txt"); NamCls NamObjVar = new NamCls(); NamObjVar.PrnFnc("Tst Txt"); } static void PlsPrnFnc(String SrgPsgVal) { System.out.println(SrgPsgVal); } void PrnFnc(String SrgPsgVal) { System.out.println(SrgPsgVal); } } 

| * | 类中的静态和非静态类:

 public class NamCls { public static void main(String[] args) { NamTicCls NamTicVaj = new NamTicCls(); NamTicVaj.PrnFnc("Tst Txt"); NamCls NamObjVar = new NamCls(); NamNicCls NamNicVar = NamObjVar.new NamNicCls(); NamNicVar.PrnFnc("Tst Txt"); } static class NamTicCls { void PrnFnc(String SrgPsgVal) { System.out.println(SrgPsgVal); } } class NamNicCls { void PrnFnc(String SrgPsgVal) { System.out.println(SrgPsgVal); } } } 

在调用实例方法或实例变量之前它需要一个对象(Instance)。 当从静态方法调用实例变量时,编译器不知道该变量属于哪个对象。 因为静态方法没有对象(总是只有一个副本)。 从实例方法调用实例变量或实例方法时,它会引用this对象。 这意味着变量属于创建的任何对象,每个对象都有自己的实例方法和变量副本。

静态变量标记为static ,实例变量没有特定关键字。

负责加载类文件的是ClassLoader。让我们看看编写自己的类时会发生什么。

例1:

 class StaticTest { static int a; int b; int c; } 

现在我们可以看到类“StaticTest”有3个字段。但实际上不存在b,c成员变量。但是为什么???。 OK Lest看到了。 这里b,c是实例变量。因为实例变量在创建对象时获取内存。 所以这里b,c还没有得到任何记忆。 这就是为什么没有b,c的存在。 所以只存在一个。 对于ClassLoader,它只有一个关于a的信息。 ClassLoader尚未识别b,c因为它的对象尚未实例化。

让我们看另一个例子:例2:

 class StaticTest { public void display() { System.out.println("Static Test"); } public static void main(String []cmd) { display(); } } 

现在,如果我们尝试编译此代码,编译器将给出CE错误。 CE:无法从静态上下文引用非静态方法display()。

现在对于ClassLoader,它看起来像:

 class StaticTest { public static void main(String []cmd) { display(); } } 

在示例2中,CE错误是因为我们从静态上下文中调用非静态方法。 因此,ClassLoader不可能在编译时识别方法display()。因此发生编译时错误。

 class MyProgram { int count = 0; // non-static variable / instance variable public static void main (String[] args) // static method { MyProgram c = new MyProgram(); // create c as reference variable System.out.println(c.count); // call non-static variable using a reference variable name (c) } } 

编译器认为“我不知道你正在谈论的是哪个对象的intance变量”。

Java在线

 body, html, iframe { width: 100% ; height: 100% ; overflow: hidden ; } 
  

试试这个..

 public class StaticTest { private int count=0; public static void main(String args[]) throws IOException { StaticTest test = new StaticTest(); //accessing static variable by creating an instance of class System.out.println(test.count); } } 

我希望它能帮助你……!