不能从静态上下文引用非静态变量

我写了这样的测试代码:

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

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

936940 次浏览

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

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

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

同时,你所看到的汽车是类“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())。

我会试着向你们解释静态的东西。首先,静态变量不属于类的任何特定实例。它们用类名来识别。静态方法也不属于任何特定的实例。它们只能访问静态变量。假设你调用MyClass.myMethod(),而myMethod是一个静态方法。如果您在方法中使用非静态变量,它究竟如何知道使用哪些变量呢?这就是为什么你只能使用静态方法中的静态变量。我再重复一遍,他们不属于任何特定的实例。

静态字段和方法连接到类本身,而不是它的实例。如果你有一个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
}
}
  • 首先要知道类的实例和类本身之间的区别。类对某些属性以及在这些属性上下文中整体的行为进行建模。实例将为这些属性定义特定的值。

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

  • 作为上述的推论

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

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

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

HTH

让我们先分析一下你的程序。 在你的程序中,你的第一个方法是main(),记住它是静态方法…然后声明该方法的局部变量(comparate、low、high等)。这个变量的作用域只是声明的方法,不管它是静态方法还是非静态方法。你不能在这个方法之外使用这些变量。这是你犯的基本错误。

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

给你们的建议是:你们误解了变量作用域和静态函数的概念。对此要有清晰的认识。

最基本的事情是静态变量或静态方法是在类级别。类级变量或方法在实例级方法或变量之前加载。显然,没有加载的东西是不能使用的。所以java编译器不让在运行时处理的事情在编译时解决。这就是为什么它会给你错误非静态的东西不能从静态上下文中引用。你只需要阅读类级作用域、实例级作用域和局部作用域。

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

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

static关键字修改类中方法或变量的生命周期。static方法或变量在装入类时创建。未声明为static的方法或变量仅在类实例化为对象(例如通过使用new操作符)时创建。

广义来说,类的生命周期是:

  1. 类的源代码是创建一个模板或 模式或戳,然后可用于
  2. 使用类使用new操作符创建一个对象,使类的实例作为实际对象,然后在处理该对象时
  3. 在垃圾收集期间销毁对象,回收它所持有的资源,例如内存。

为了为应用程序提供一个初始入口点,Java采用了这样的约定:Java程序必须有一个类,该类包含一个具有一致同意的或特殊名称的方法。这个特殊的方法叫做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()方法之外且没有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
}
}

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

示例1:

class StaticTest {


static int a;
int b;
int c;
}
现在我们可以看到类“StaticTest”有3个字段。但实际上不存在b c成员变量。但是为什么??好的,让我看看。这里b c是实例变量。因为实例变量在对象创建时获得内存。所以这里b c还没有内存。这就是不存在b c的原因。所以只有a的存在。 对于ClassLoader,它只有一个关于a的信息。ClassLoader还不能识别b,c,因为它的对象还没有实例化 让我们看另一个例子: 示例2:< / p >
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()。因此会发生编译时错误。

这是为所有初学者解释静态关键字的bit diff 当你更多地使用类和对象时,你会更清楚地了解它

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

NamCls.NamFnc();


System.out.println();

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

|*| __abc0非静态项可以使用类变量
调用 如果它不是静态的,你需要一个类的变量
在类变量后面加上点,并且
然后调用function.

NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();
人力资源> < p > < 下面的代码清楚地解释了你

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

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);
}
}
人力资源> < p > < |*|类中的静态和非静态类:

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,实例变量没有特定的关键字。

在这个程序中,你想使用count,所以将count方法声明为静态方法

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

您可以将此方法声明为公共私有并受保护。如果使用此方法,则可以创建安全应用程序。

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

在Java编程语言中,关键字static表示特定成员属于类型本身,而不是该类型的实例。

这意味着只创建了static成员的一个实例,该实例在类的所有实例中共享。

所以如果你想在static void main()中使用你的int count = 0;count变量必须声明为static

static int count = 0;

这是因为您不创建模型类的实例,您必须在每次使用非静态方法或变量时创建实例。

你可以很容易地修复这个,看看下面的图片

Without Instance making .

没有创建类的实例

enter image description here

我的模型类文件

enter image description here

通过创建实例,然后使用类的非静态方法或变量,很容易出错