Re: how to get the type info from this small code snippet?

David Hovemeyer <[email protected]>
Newsgroups gmane.comp.jakarta.bcel.user
Message-ID <[email protected]>
On Wed, Jan 26, 2005 at 12:57:23PM -0700, Hiller, Dean D (Dean) wrote:
> I am a little confused on scanning for this
>   LDC "com.foobar.SomeClass"
>   INVOKESTATIC "java.lang.Class class$(java.lang.String)"
> 
> The closest thing I see is this
>          instr=aload_0[42](1)
>          instr=invokestatic[184](3) 1
> 
> I think I tried to get the type info from the aload_0 and failed.  How
> do I get aload_0, type info.

I don't think that is the instruction pair that gets the class
object.  In general, you need to perform a dataflow analysis
to find out what type of reference is stored in a local.
However, for non-static methods, aload_0 will almost certainly
load the "this" reference, which is of the type of the class
the method is in.

Here is what I see using javac from JDK 1.4.2_04 on the following
sample class:

public class GetClass {
	public Class c = GetClass.class;
}


Output from "javap -c -private GetClass":

Compiled from "GetClass.java"
public class GetClass extends java.lang.Object{
public java.lang.Class c;
 
static java.lang.Class class$GetClass;
 
public GetClass();
  Code:
   0:   aload_0
   1:   invokespecial   #6; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   getstatic       #7; //Field class$GetClass:Ljava/lang/Class;
   8:   ifnonnull       23
   11:  ldc     #8; //String GetClass
   13:  invokestatic    #9; //Method class$:(Ljava/lang/String;)Ljava/lang/Class;
   16:  dup
   17:  putstatic       #7; //Field class$GetClass:Ljava/lang/Class;
   20:  goto    26
   23:  getstatic       #7; //Field class$GetClass:Ljava/lang/Class;
   26:  putfield        #10; //Field c:Ljava/lang/Class;
   29:  return
 
static java.lang.Class class$(java.lang.String);
  Code:
   0:   aload_0
   1:   invokestatic    #1; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
   4:   areturn
   5:   astore_1
   6:   new     #3; //class NoClassDefFoundError
   9:   dup
   10:  aload_1
   11:  invokevirtual   #4; //Method java/lang/ClassNotFoundException.getMessage:()Ljava/lang/String;
   14:  invokespecial   #5; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
   17:  athrow
  Exception table:
   from   to  target type
     0     4     5   Class java/lang/ClassNotFoundException

Bytecodes 11 and 13 in the constructor are the sequence I was
talking about.

You can also see a synthetic static field (class$GetClass) to cache
the Class object, and a synthetic static method (class$) which takes
a String object (class name), does the class lookup using Class.forName(),
and returns it.

In the code you posted:

      method=<init>
         method ret type=void
         instr=aload_0[42](1)
         instr=invokespecial[183](3) 6
         instr=aload_0[42](1)
         instr=getstatic[178](3) 7
         instr=ifnonnull[199](3) -> getstatic 7
         instr=ldc[18](2) 8
         instr=invokestatic[184](3) 9
         instr=dup[89](1)
         instr=putstatic[179](3) 7
         instr=goto[167](3) -> putfield 10
         instr=getstatic[178](3) 7
         instr=putfield[181](3) 10
         instr=return[177](1)

My guess is that the lines

         instr=ldc[18](2) 8
         instr=invokestatic[184](3) 9

are where the "class$" method is being called.  It's easier to
see using "javap -c", though, since that shows all of the symbolic
information like method names, signatures, constant values,
etc.

-Dave
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.