int i = 100; //对象属性;
static int j = 200;//类属性,不依赖于创建的对象;
创建对象时,需要new 构造函数,在创建对象时不可能使用要创建对象的属性。比如,你不能吃你明天才能吃到的饭一样。
static int j = 200;//类属性,不依赖于创建的对象;
创建对象时,需要new 构造函数,在创建对象时不可能使用要创建对象的属性。比如,你不能吃你明天才能吃到的饭一样。
解决方案 »
- 如何设置ThreadStackSize大小 ?顶者给分,急。
- 百分求解:JAVA组播难题
- 我将一个xml协议报文类实例化后放入队列,提示没有序列化,但我已经实现了序列化!
- JDBC Driver连接sql server时,出现“Error establishing socket.”的问题。
- java中如何实现这个功能?请高手不吝赐教
- 菜鸟顿悟面向对象及隐藏实施的意思,菜鸟来看吧
- 请问:我写的java程序,已可以在命令行下运行了,但不知道怎么把它变成成一个图标,双击图标就可以运行了呢?
- 如何获得鼠标事件并得到其位置?
- Applet中的ArrayList怎么传到javascript中,反之,js中的数组如何传入APPLET中?
- 冒泡排序与选择排序。。。
- 我写的Java程序怎给没Java环境的人用?
- 怎么连接不上数据库?大家帮我看看吧
MyDemo ob = new MyDemo();
}}class MyDemo extends MyFather { int i = 100;
static int j = 200; public MyDemo() {
System.out.println("这是MyDemo的无参构造器输出的");
//super(j); // 这里为什么一定要用 j 不能用 i ,网上说是因为 i 还没有被初始化, 但为什么上面 注释1
// 的代码执行却可以,Java 的对象初始化究竟是怎样的。
}}class MyFather { public MyFather() {
System.out.println("这是MyDemo的父类MyFather的无参构造函数输出的!");
} public MyFather(int i) {
// TODO Auto-generated constructor stub
}}运行输出结果是:
这是MyDemo的父类MyFather的无参构造函数输出的!
这是MyDemo的无参构造器输出的执行流程是这样的:先从入口main处执行,在main里我们实例化了一个MyDemo对象,而MyDemo类是MyFather的子类,所以在实例化MyDemo类时,默认情况下是会执行其父类的无参构造函数的,然后再去执行MyDemo自身的构造器。
回到问题,因为你在实例化MyDemo时,不管你执行的是MyDemo的有参或是无参构造器,在MyDemo实例化之前先要实例化其父类的构造器,i 成员属性是需要实例化之后才能用的,而 j 是类属性,属性自身类的,无须实例化就能用。
int i;
static int j; public MyDemo();
Code:
0: aload_0
1: invokespecial #1 // Method MyFather."<init>":()V 没有调用super
4: aload_0
5: bipush 100 // 将100 保存到 i
7: putfield #2 // Field i:I // 关键点在这里 Print 之前 已经替你做好初始化了
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_0
14: getfield #2 // Field i:I
17: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
20: return
LineNumberTable:
line 13: 0
line 10: 4
line 13: 10 static {};
Code:
0: sipush 200
3: putstatic #5 // Field j:I
6: return
LineNumberTable:
line 11: 0
}
public static void main(String[] args) {
MyDemo ob = new MyDemo();
}
}
class MyDemo extends MyFather {
int i = 100;
static int j = 200;
public MyDemo() {
super();
}
}
class MyFather {
public MyFather() {
}
public MyFather(int i) {
}
}
Compiled from "java.java"class MyDemo extends MyFather {
int i; static int j; public MyDemo();
Code:
0: aload_0
1: invokespecial #1 // Method MyFather."<init>":()V 关键点在这里 1. 先调用了super
4: aload_0
5: bipush 100
7: putfield #2 // Field i:I 2. 再初始化 i 的。 所以 i 是null 或默认值
10: return // 其实 应该是可以用null 或 默认值 调用Super的吧(我想C++或许可以)
LineNumberTable: // 或许Java是为了安全和健壮才不让这么做的
line 16: 0
line 10: 4
line 18: 10 static {};
Code:
0: sipush 200
3: putstatic #3 // Field j:I
6: return
LineNumberTable:
line 11: 0
}
当你创建MyDemo的对象ob的时候:
第一步,JVM会先为对象的实例变量i分配内存空间并给默认值,int的默认值就是0,于是此时i为0
第二步,为变量初始化,这个时候则会先依次调用父类的非静态初始化块和构造器部分(分显式和隐式),然后才是调用本类的非静态初始化块和构造器,当然你这里用的显式调用(也就是你super(j)这一句)
所以如果你调用super(i)的话,其实i已经被分配了内存空间,值为0
但是会报编译错误,可能是因为此时i必然是默认值,编译器认为没有意义?