Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Initialization of an interface  RSS feed

 
Rauhl Roy
Ranch Hand
Posts: 401
Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't understand the execution of this program. In other words, please explain me the Initialization of an interface.

interface I {
int i = 1, ii = Test.out("ii", 2);
}
interface J extends I {
int j = Test.out("j", 3), jj = Test.out("jj", 4);
}
interface K extends J {
int k = Test.out("k", 5);
}
class Test {
public static void main(String[] args) {
System.out.println(J.i);
System.out.println(K.j);
}
static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}
}
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66188
151
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The code you posted won't even come close to compiling. Interfaces do not posess implementation code. Search this forum for previous discussions on what an interface is, and is not.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, it does compile. The "constants" in an interface don't actually have to be compile-time constants, although they can be; some of these are, and some are not, making this code hard to understand.

First, the value of J.i is determined at compile time and the value is substituted. The line of code

System.out.println(J.i);

is actually compiled as if it were

System.out.println(1);

So we see the "1" printed first.

Now, remember that variables are never polymorphic, be they static or otherwise. So the compiler knows that a reference to "K.j" actually means "J.j" at compile time. Therefore the second println() compiles as if it were

System.out.println(J.j);

Because this isn't a compile-time constant, the class file "J" needs to be loaded and initialized to evaluate it. Because none of the data members in J mention any members in I, I doesn't need to be initialized, although I believe it will be loaded (K might actually be loaded, too, although again, since no members are mentioned, it's not initialized.) Anyway, so when you print J.j, you see J's two data members being initialized before you finally see the value of j.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66188
151
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right and I stand corrected! The unformatted code makes it hard to see the braces and I missed a few.
 
Abdul Rehman
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a very subtle difference between initialization of classes & interfaces. In case of classes, initialization of a class will not occur until its superclass has been initialized, which in turn will not be initialized till its superclass is initialized and this will continue till java.lang.Object has been initialized.
In case of interface, the initialization of an interface will NOT of itself cause initialization of a superinterface.

Here is a sample code which illustrates the above point.

The output from the above code is:

test = 10
5
test = 40
test = 43
40


At statement (1), we access a static (not compile-time constant) member of class B. But, before class B is loaded, its superclass (A) is loaded, executing its static initializers.
On the other hand, when we access a static (not compile-time constant) final member of interface J, its superinterface (I) is NOT loaded. Only the interface J is loaded & its static initializers are executed. This can be clearly seen from the output.

Best regards,
Abdul Rehman.
[ November 24, 2006: Message edited by: Abdul Rehman ]
 
Rauhl Roy
Ranch Hand
Posts: 401
Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
Actually, it does compile. The "constants" in an interface don't actually have to be compile-time constants, although they can be; some of these are, and some are not, making this code hard to understand.

First, the value of J.i is determined at compile time and the value is substituted. The line of code

System.out.println(J.i);

is actually compiled as if it were

System.out.println(1);

So we see the "1" printed first.

Now, remember that variables are never polymorphic, be they static or otherwise. So the compiler knows that a reference to "K.j" actually means "J.j" at compile time. Therefore the second println() compiles as if it were

System.out.println(J.j);


Because this isn't a compile-time constant, the class file "J" needs to be loaded and initialized to evaluate it. Because none of the data members in J mention any members in I, I doesn't need to be initialized, although I believe it will be loaded (K might actually be loaded, too, although again, since no members are mentioned, it's not initialized.) Anyway, so when you print J.j, you see J's two data members being initialized before you finally see the value of j.

I do not understand this para. Could you please tell me once again?

[ November 25, 2006: Message edited by: Rauhl Roy ]
[ November 25, 2006: Message edited by: Rauhl Roy ]
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!