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

时间:2012-11-19 23:12:53

标签: java static

  

可能重复:
  What is the reason behind “non-static method cannot be referenced from a static context”?

我是Java新手。我有以下几组代码。

class Default
{
    private short s;
    private int i;
    private long l;
    private float f;
    private double d;
    private char c;
    private String str;
    private boolean b;

    public static void main (String args[ ])
    {

        Default df = new Default();

        System.out.println("\n Short = "+s);

        System.out.println ("\n int i =" + i);
        System.out.println ("\n long l =" + l );
        System.out.println ("\n float f =" + f);
        System.out.println ("\n double d =" + d);
        System.out.println ("\n char c =" + c);
        System.out.println ("\n String s =" + str);
        System.out.println("\n boolean b =" + b);
    }
}

这会产生一条错误消息,作为此问题的主题,但以下代码可以正常运行。

class Default
{
    private short s;
    private int i;
    private long l;
    private float f;
    private double d;
    private char c;
    private String str;
    private boolean b;

    public static void main (String args[ ])
    {

        Default df = new Default();

        System.out.println("\n Short = "+df.s);

        System.out.println ("\n int i =" + df.i);
        System.out.println ("\n long l =" + df.l );
        System.out.println ("\n float f =" + df.f);
        System.out.println ("\n double d =" + df.d);
        System.out.println ("\n char c =" + df.c);
        System.out.println ("\n String s =" + df.str);
        System.out.println("\n boolean b =" + df.b);
    }
}

这给出了期望的结果。这两组代码有什么区别。

2 个答案:

答案 0 :(得分:2)

您有一个名为Default的{​​{1}}实例化对象,它正在调用这些变量。由于您创建的变量不是df,因此它们必须与已创建的某个对象分开。

static

如果不与对象一起使用,则使用关键字Default df = new Default(); df.i //<- is now a part of the instantiated object df. 。所以你可以说:

static

然后您可以随时拨打private static char c; ,这将是char c,因为您还没有给它一个值。

当您使用没有对象的变量或方法时,可以使用null

答案 1 :(得分:1)

两组代码之间的区别在于,在第二个示例中,您有一个类的实例,当您说Default df = new Default();时就会创建该实例。

您已将Default类中的所有变量声明为实例级变量,这意味着为了访问它们,您必须通过类的特定实例。或者换句话说,类的每个实例都有自己的变量集,因此编译器知道您实际访问哪一个的唯一方法是指定要首先使用的实例。

例如,你可以这样做:

Default df = new Default();
Default anotherOne = new Default();

df.s = 1;
anotherOne.s = 2;

System.out.println("\n Short(df) = "+df.s);                  //'1'
System.out.println("\n Short(anotherOne) = "+anotherOne.s);  //'2'

尝试直接从main()(或从任何其他静态方法)访问实例变量的问题是main()方法与您的类的任何实例都没有直接关联。因此,在这种情况下,编译器不知道从哪个实例获取变量,除非您明确指定一个。

当然,您可以将变量设置为静态,但是每个实例不是一组值,而是为类创建一组变量,无论您创建多少个实例。在这种情况下,示例中的代码仍将编译并运行(尽管它会/应该产生编译器警告),但两个语句都会打印'2',因为只有一个s变量每个班级的一个。