Hi.
While I'm writing codes on call graph construction of Java programs,
I've got a question.
I'm wondering how the class name in the argument of invokevirtual is
determined.
Is it the name of a class containing the method definition?
The code snippet (1) is compiled into the bytecode (2).
Neither printStackTrace() nor equals() are not defined in the
AWTException.
But the class name of the first invokevirtual is AWTException,
whereas the class name of the second invokevirtual is Object. Why is
that?
I'd appreciate it if you'd let me know how the class name of
invokevirtual is determined.
(1)
java.awt.AWTException e1 = new java.awt.AWTException("1");
java.awt.AWTException e2 = new java.awt.AWTException("2");
e1.printStackTrace();
e1.equals(e2);
(2)
aload_1
invokevirtual #6; //Method java/awt/AWTException.printStackTrace:()V
aload_1
aload_2
invokevirtual #7; //Method
java/lang/Object.equals:(Ljava/lang/Object;)Z
Thanks.
Regards,
Toby Kim
Chris Uppal - 22 Aug 2006 16:25 GMT
> While I'm writing codes on call graph construction of Java programs,
> I've got a question.
> I'm wondering how the class name in the argument of invokevirtual is
> determined.
> Is it the name of a class containing the method definition?
Not usually, at least not for Java compiled by a compiler which obeys the JLS
(there are other sources of legal bytecode, of course). The full rules are set
out in section 13.1 of the JLS (part of the binary compatibility stuff).
Ignoring various complications, the rule is that the class name is the name of
the type of the expression whose value is the target of the method invocation
(any kind of method invocation). That is /unless/ the method is one of the
methods defined by Object, in which case the class name is required to be
Object.
So in your example, if you had declared your two variables to have type
java.lang.Exception then the invokevirtual would invoke java/lang/Exception
printStackTrace()V. If you had declared e1 as a java.lang.Throwable then the
invokevirtual would name that class instead. OTOH,
equals:(Ljava/lang/Object;)Z is defined by Object, so any invocation of that
method must name java/lang/Object.
I have, by the way, no idea at all what benefit there is supposed to be in
making java.lang.Object a special case. I suspect there is none...
-- chris
Thomas Hawtin - 22 Aug 2006 17:09 GMT
> While I'm writing codes on call graph construction of Java programs,
> I've got a question.
[quoted text clipped - 8 lines]
> whereas the class name of the second invokevirtual is Object. Why is
> that?
The parameter and return types must always match. Working out which
overloaded method to use is done at compile time. In 1.5+, the compiler
synthesises bridge methods for covariant return types.
Which class the method is declared on is not important. Indeed binary
compatibility requires that a method may be moved to a super class.
For methods declared in interfaces, it is preferable to use a class type
if possible because dispatch on a class type is often faster than on an
interface type.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/