黑马程序员技术交流社区

标题: 疑问 [打印本页]

作者: Hugoo    时间: 2014-6-30 09:07
标题: 疑问
demo 1:
class Foo {
int x = 3;

public static void main(String[] args) {
Foo a = new Foo();
System.out.println(a.x);
}
}
这段代码可以通过编译并运行
demo2:
class Foo {
int x = 3;
Foo a = new Foo();
public static void main(String[] args) {

System.out.println(a.x);
}
}
这段代码就不行

原因:{静态的main方法不能访问实例变量(非静态变量)}
这种解释不能令人信服,Demo1就通过测试了啊,到底是什么原因?

我又遇到了新问题,
demo1:出错
class Foo {
int x = 3;
Foo a = new Foo();
public static void main(String[] args) {
   Foo b = new Foo();

  System.out.println(b.x);
}
}
错误提示如下
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)
at Foo.<init>(Foo.java:3)

Demo2我仅仅删掉了一句话,变成
class Foo {
int x = 3;

/*Foo a = new Foo();
public static void main(String[] args) {
   Foo b = new Foo();

  System.out.println(b.x);
}
}
运行没有任何问题
作者: Hugoo    时间: 2014-6-30 09:17
这个其实涉及到类里面的成员或方法何时初时化的问题

解析DEMO1:
大致可认为:初始化Foo这个类(是类,而不是这个类的实例),这时x变量还没有初始化,它先初始化这个类变量及类方法(通俗点就是静态变量及静态方法):这里就一个main方法。
很显然,由于main方法是有特殊性的:它会被调用,这时它创建了一个Foo的一个实例:Foo a = new Foo();这个时候,才会有一个Foo的实例被创建,并且给x赋值。所以你能打印时能访问到a.x

初始化类、对象的异同点:
初始化类的时候,它可能只是告诉虚拟机:有Foo这么一个类,它有一个x的变量,这个变量是int型的,它还有一个main方法
初始化类的实例时,它是在内存中划出一块来放Foo,并且给x赋值:3

根据以上大致分析,再看demo2:x, Foo a这两个东西其实都不存在于内存中,当然访问不到。

很久没看<深入JVM>了,推荐这本书给你
demo 1:
class Foo {
int x = 3;

public static void main(String[] args) {
Foo a = new Foo();
System.out.println(a.x);
}
}

提问者评价

    非常感谢你的回答,同时 liyingjie1的回答也很好,还有好几个人的回答都很棒,这里一并表示感谢!


作者: blue_sky    时间: 2014-6-30 09:22
主函数前面的修饰符里含有static:静态修饰符;
使用static修饰的静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)
class Foo {
int x = 3;
Foo a = new Foo();//当加载这个类的时候,这个类不会被创建,只有使用这个对象的时候,才会被创建;
public static void main(String[] args) {//而主函数时静态的,只能访问静态的方法,所以访问不到a对象;
   Foo b = new Foo();

  System.out.println(b.x);
}
}

这个问题主要是Static修饰符的原因;
作者: Hugoo    时间: 2014-6-30 09:30
解决难题不容易,需持之以恒
作者: 郑飞    时间: 2014-6-30 14:55
楼主 liyingjie1是谁啊:dizzy:




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2