注册 登录
编程论坛 JAVA论坛

[求助]有关接口初始化的问题?

Sieben7 发布于 2007-11-12 15:58, 1939 次点击
interface I {
int i = 1, ii = Outer.out("ii", 2);
}

interface J extends I {
int j = Outer.out("j", 3), jj = Outer.out("jj", 4);
}

interface K extends J {
int k = Outer.out("k", 5);
}

public class Outer {
public static void main(String[] args) {
System.out.println(K.j);
}

public static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}
}

28 回复
#2
Sieben72007-11-12 15:59

请问这里I和K两个接口是否不进行初始化了?我对这题的理解有些混乱。

谢过~
#3
Sieben72007-11-12 15:59
输出结果是:
j=3
jj=4
3
#4
hwoarangzk2007-11-12 16:13

你把main里面换成System.out.println(K.i)和System.out.println(K.k),看看结果再想想

#5
Sieben72007-11-12 16:24
谢谢你。我试了下。不过这边我没有调用jj啊,可是为什么还是会输出jj=4 ?
#6
hwoarangzk2007-11-12 16:40
int j = Outer.out("j", 3), jj = Outer.out("jj", 4);
这句话有逗号表达式,也就是说执行了Outer.out("j", 3), jj = Outer.out("jj", 4)这两句话,所以会出现jj=4
#7
Sieben72007-11-12 16:45
按照你所说的,我把main里面换成System.out.println(K.i),照理说输出应该是1,ii=2
可是输出结果是:1
后面的ii=2没有输出,这是为什么呢?前面也有逗号表达式哇...
#8
hwoarangzk2007-11-12 16:56
int i = 1, ii = Outer.out("ii", 2);
int j = Outer.out("j", 3), jj = Outer.out("jj", 4);
这两句话使输出一个只有1行,另一个有3行
#9
hwoarangzk2007-11-12 17:43
这个应该是跟out是静态方法有关,这个方法在内存中只有一个位置, System.out.println(K.j),如果int j = Outer.out("j", 3), jj = Outer.out("jj", 4);
那么这两个调用都会执行,而如果改成int j = 3, jj = Outer.out("jj", 4),这样的话因为j=3并没有调用out方法,所以后面的jj=Outer.out("jj",4)也就没有调用了
#10
huwangvs2007-11-12 18:34
版主解释好像有误啊。
和逗号表达式没关系吧?应该是加载问题。
而你说的
[QUOTE]这个应该是跟out是静态方法有关,这个方法在内存中只有一个位置, System.out.println(K.j),如果int j = Outer.out("j", 3), jj = Outer.out("jj", 4);
那么这两个调用都会执行,而如果改成int j = 3, jj = Outer.out("jj", 4),这样的话因为j=3并没有调用out方法,所以后面的jj=Outer.out("jj",4)也就没有调用了[/QUOTE]
我加了一个方法,和out一样,就是名字不同。调用后,两个依然打印啊。。。。
具体情况,不清楚。。。还是基础不行啊
#11
Sieben72007-11-12 18:37
这个么。。。

[此贴子已经被作者于2007-11-12 18:37:52编辑过]

#12
huwangvs2007-11-13 08:56

昨天回去看了看。找到原因了。
原因就是final修饰符。
如果final修饰的是基本类型且这个基本类型已经赋了值。那么它就在编译器提前赋值。。那么在运行期就无须初始化而直接使用。此时就不用再加载包含它的类了。。所以K.i只打印一行。即i的值。
而如果final修饰类型为非基本类型,或以表达式赋值。那么它还是在运行期初始化。此时就需要加载包含它的类了。。
在此例中因为属性默认都是static的。所以在加载类的同时,都会初始化。所以K.j才会打印出三行来。

#13
hwoarangzk2007-11-13 09:23
可是final在哪儿啊?
#14
huwangvs2007-11-13 09:40
接口里属性默认是static final的。。。
#15
hwoarangzk2007-11-13 09:48
你把你写的那段代码发上来看下吧
#16
hwoarangzk2007-11-13 09:50

interface I {
int i = 1, ii = Outer.out("ii", 2);
}

interface J extends I {
int j = Outer.out("j", 3), jj = Outer.out1("jj", 4);
}

interface K extends J {
int k = Outer.out("k", 5), kk = Outer.out("kk", 6);
}

public class Outer {
public static void main(String[] args) {
System.out.println(K.j);
}

public static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}

public static int out1(String s, int i){
System.out.println(s+"="+i);
return i;
}
}
原来如此,明白了,没注意到这个问题...

#17
huwangvs2007-11-13 10:00
回去debug了半天。。。感觉是final的问题。。。在thinking in java里还真找到了。。。
这种折磨人的问题也只有找thinking in java了。。。。
#18
hwoarangzk2007-11-13 10:06
很多细节问题都没注意到...要好好复习一下了
#19
huwangvs2007-11-13 10:11

做开发很少遇到这种问题。。
谁没事写这种蹩脚的程序啊
以后还得多来看看开发太模式化了。

#20
huwangvs2007-11-13 10:13
这程序还让我发现Intellij IDEA一个bug。。。
打印K.i的时候,直接运行打印1.。。debug就打印ii=2,1。。。郁闷半天。。。
#21
Sieben72007-11-14 14:54
看来讨论的很深嘛,太谢谢两位了~受益匪浅~

#22
狂放不羁2007-11-14 16:29
这是关于类加载和静态初始化的问题.接口中默认的数据都是public static final,当你访问K.k的时候,因为k是K接口新增加的,所以它的初始化也许会依赖于父接口.所以会会以I,J,K的顺序来加载接口.(当加载完成后无论是接口还是类,第一步要做的工作就是静态代码的执行和静态数据的初始化,但是对于接口来说是从当前的接口开始初始化,而对于类来说要从最顶层的类开始执行初始化代码).但是当你访问k.i的时候,i是最顶层的接口继承来的成员,它不依赖于父接口,关键是它是个静态编译期常量!!所以可以直接用接口名来访问。此时就只能输出1.希望LZ用
java -verbose Outer来看看类和接口是如何加载到内存中的.

[此贴子已经被作者于2007-11-14 17:57:17编辑过]

#23
hwoarangzk2007-11-14 16:44
顶狂放兄一个
#24
狂放不羁2007-11-14 16:46

呵呵。

#25
huwangvs2007-11-14 17:15

再来叫个板。。呵呵。。。

[QUOTE]当你访问k.i的时候,i是最顶层的接口继承来的成员,它不依赖于父接口,所以此时直接加载K接口.[/QUOTE]
既然加载了K。。那么怎么没有初始化k呢???

#26
狂放不羁2007-11-14 17:55
以下是引用huwangvs在2007-11-14 17:15:59的发言:

再来叫个板。。呵呵。。。

当你访问k.i的时候,i是最顶层的接口继承来的成员,它不依赖于父接口,所以此时直接加载K接口.

既然加载了K。。那么怎么没有初始化k呢???

不好意思。此时i是编译期常量。不需要加载K。呵呵。不过加载和初始化是完全不同的两个过程。默认情况下是加载后,直接进行默认的静态初始化动作。但是在反射中,如果改变加载器的参数则是用到的时候才初始化,不一定加载后就非要初始化的。

[此贴子已经被作者于2007-11-14 17:58:45编辑过]

#27
huwangvs2007-11-14 18:13
#28
Sieben72007-11-14 19:55
呵呵,很厉害的版主~
#29
Sieben72025-05-08 08:50
时隔十几年,如今仍旧一脸懵
1