Page 2 of 2
public static native void getenv (String evName, StringBuffer evValue);
maps to the following C++ function:
Java_SysInfo_getenv__Ljava_lang_String_2Ljava_lang_StringBuffer_2
This function contains a call to CallObjectMethod, a JNI function, which calls the StringBuffer object's append method. The append method gives us the ability to append characters to the end of a StringBuffer object. Note that it is important to initialize the StringBuffer object to the empty string before calling this getenv method. If this is not done, then it is possible that the StringBuffer object will have the value of the environment variable appended to whatever is already in the object.
The Java_SysInfo_getVersion function gets the operating system's version number. This function calls a JNI function called AllocObject to allocate the necessary memory for a Java object. The object's constructor is not called. A separate JNI function, NewObject could be called to call the constructor after allocating memory (if desired). If you examine this code, you'll notice that
this object is based on a class called Version (see the code snippet below). The major and minor data fields of this object are populated and then a reference to this object is returned.
public class Version
{
int major;
int minor;
}
If a class has no constructor, Java gives the class a default constructor that takes no arguments and has no functionality. I do not believe that failing to call a constructor for such a class will result in serious consequences.
For those who are interested, the code that follows contains the Java virtual machine code for an empty constructor.
; 1. Load the "this" reference to this object onto the operand ; stack. aload_0 ; 2. Invoke the constructor for the ultimate Object superclass. invokespecial java/lang/Object/<init>()V ; 3. Return to the invoker method. return
NOTE: This article was built with JDK 1.1.5 and Win32.
This article has shown what happens when a Java native method is called that takes an object reference argument -- and C++
code needs to interact with that object via the JNI. Our example showed a getenv method being called with a StringBuffer reference argument. The C++ logic used the JNI to call the append method to append a sequence of characters to the StringBuffer object reference. We also looked at creating an object from C++, populating its data fields, and then returning a reference
to this object. We did not call the constructor because there wasn't one to call besides an empty default constructor. Finally,
we looked at the Java virtual machine code that makes up this empty constructor.
Although we could have done all of this in Java without needing to resort to the JNI, you never know when such knowledge might come in handy -- especially if your Java application must communicate with legacy code via the JNI.