首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不能从静态上下文引用非静态变量

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

Stack Overflow用户
提问于 2010-04-01 17:57:20
回答 14查看 828K关注 0票数 339

我写了下面的测试代码:

代码语言:javascript
运行
复制
class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}

但它会给出以下错误:

代码语言:javascript
运行
复制
Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^

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

EN

回答 14

Stack Overflow用户

发布于 2010-04-01 18:10:39

您必须了解类和该类的实例之间的区别。如果你在街上看到一辆车,即使你看不清是哪种型号或类型,你也能立刻知道那是一辆车。这是因为您将看到的内容与类"car“进行了比较。这个类包含了类似于所有汽车的内容。可以把它想象成一个模板或者一个想法。

同时,您看到的汽车是" car“类的一个实例,因为它具有您期望的所有属性:有人驾驶它,它有一个引擎和轮子。

所以类说“所有的汽车都有一种颜色”,实例说“这个特定的汽车是红色的”。

在面向对象的世界中,您定义类,并在类内部定义Color类型的字段。实例化类时(当您创建特定实例时),会为颜色保留内存,您可以为此特定实例指定颜色。因为这些属性是特定的,所以它们是非静态的。

静态字段和方法与所有实例共享。它们用于特定于类的值,而不是特定的实例。对于方法,这通常是全局助手方法(如Integer.parseInt())。对于字段,它通常是常量(比如汽车类型,即你有一个有限的集合,不会经常改变)。

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

在您的示例中,尝试将此代码作为开始块:

代码语言:javascript
运行
复制
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())。

票数 351
EN

Stack Overflow用户

发布于 2010-04-01 18:14:51

静态字段和方法连接到类本身,而不是它的实例。如果您有一个类A、一个“普通”(通常称为实例)方法b和一个静态方法c,并且您为您的类A创建了一个实例a,则对A.c()a.b()的调用是有效的。方法c()不知道连接了哪个实例,因此它不能使用非静态字段。

您的解决方案是,要么将字段设置为静态,要么将方法设置为非静态。你的main可能看起来像这样:

代码语言:javascript
运行
复制
class Programm {

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

    public void start() {
        // can now access non-static fields
    }
}
票数 105
EN

Stack Overflow用户

发布于 2015-01-16 23:37:23

static关键字修改类中方法或变量的生命周期。static方法或变量是在加载类时创建的。只有当类被实例化为对象时,才会创建未声明为static的方法或变量,例如,使用new操作符。

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

  1. 类的源代码是这样编写的:创建一个模板或模式或戳,然后可以使用这些模板或模式或戳创建一个带有new运算符的对象,使用类将类的一个实例作为实际对象创建,然后在完成对象后
  2. 销毁该对象,在垃圾收集期间回收它所持有的资源(如内存)。

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

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

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

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

代码语言:javascript
运行
复制
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
    }
}
票数 71
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2559527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档