JNI/NDK Development Guide (eight)--call constructor method and parent class instance method

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/xyang81/article/details/44002089

In the 6th chapter, we learned how to invoke Java static methods and instance methods at the native layer, where the example code that invokes the instance method also mentions the call constructor to actually start an object, but it's not covered in detail. Students who have not read please visit the JNI/NDK Development Guide (vi)--c/c++ Access to Java instance methods and static methods read. This chapter details two ways to start an object, and how to invoke the parent class instance method of the child class object override.

Let's go back to the process of instantiating an object in Java and invoking the parent class instance method. Look at the code first:

 PackageCom.study.jnilearn; Public  class Animal {     Public void Run() {System.out.println ("Animal.run ..."); }} PackageCom.study.jnilearn; Public  class Cat extends Animal {    @Override     Public void Run() {SYSTEM.OUT.PRINTLN (name +"Cat.run ..."); }} Public Static void Main(string[] args) {Animal cat =NewCat ("Tom"); Cat.run ();}

As you can see, the above code is very simple, there are two classes animal and Cat,animal classes defined in the run and GetName two methods, cat inherits from Animal, and overrides the parent class of the Run method. In the main method, you first define a variable cat of type animal, point to the instance object of the Cat class, and then call its Run method. when the new Cat ("Tom") code is executed, the cat class is allocated a memory space (the amount of memory allocated is determined by the number of member variables in the Cat class) and then called by the cat's parameter constructor method to initialize the object. Cat is a animal type, but it points to a reference to the cat instance object, and cat overrides the parent class's Run method because there is a polymorphic presence when calling the Run method, so it accesses the cat run instead of the animal run, and the result is printed as follows: Tom Cat.run ...
If you want to call the Run method of the parent class, simply call Super.run () in the cat's Run method, which is fairly straightforward.

C or C + + students should have a very deep memory management concept, stack space and heap space, the memory size of the stack space is limited by the operating system, automatically managed by the operating system, faster, so the function is defined in the local variables, function-shaped parametric are stored in the stack space. The operating system does not limit the amount of memory in the heap space, only limited by physical memory, which needs to be managed by the programmer. Memory allocated dynamically with the malloc keyword in the C language and allocated memory for objects created with new in C + + are stored in the heap space and freed with free or delete/delete[when memory is used. here is not too much to discuss the C + + memory management knowledge, interested students please self-Baidu. children's shoes for Java it is well known that writing Java programs does not require manual management of memory, memory management Those annoying locks are managed by a thread called GC (when an object is not referenced by another object, the object is freed by the GC). But I think the principle of memory management inside Java is very similar to that of C + +, in the example above, Animal cat = new Cat ("Tom"); The local variable cat is stored on the stack space, New Cat ("Tom"); The created instance object is stored in the heap space and returns a reference to the memory address stored in the Cat variable. This makes it possible to access all the visible members of the cat instance through the reference pointed to by the cat variable.

So creating an object is divided into 2 steps:
1. Allocating memory space to objects
2. Initialize the object (Call object construction method)

Here's an example of how the object construction method and the parent class instance method are called in JNI. To allow the example to clearly reflect the invocation process of the constructor and the parent instance method, define the animal and cat two classes, animal defines a string parameter construction method, a member variable name, two member functions run and GetName, Cat inherits from Animal and overrides the Run method. Implements an instance of creating a Cat object in JNI, invoking the run and GetName methods of the animal class. The code looks like this:

//Animal.java PackageCom.study.jnilearn; Public  class Animal {    protectedString name; Public Animal(String name) { This. name = name; System.out.println ("Animal Construct call ..."); } PublicStringGetName() {System.out.println ("Animal.getname call ...");return  This. Name; } Public void Run() {System.out.println ("Animal.run ..."); }   }//Cat.java PackageCom.study.jnilearn; Public  class Cat extends Animal {     Public Cat(String name) {Super(name); System.out.println ("Cat Construct call ...."); }@Override     PublicStringGetName() {return "My name is"+ This. Name; }@Override     Public void Run() {SYSTEM.OUT.PRINTLN (name +"Cat.run ..."); }}//Accesssupermethod.java PackageCom.study.jnilearn; Public  class accesssupermethod {     Public native Static void Callsuperinstancemethod(); Public Static void Main(string[] args)    {Callsuperinstancemethod (); }Static{System.loadlibrary ("Accesssupermethod"); }}

The Accesssupermethod class is the entry for the program, which defines a native method Callsuperinstancemethod. The JNI function prototype generated with Javah is as follows:

/* Header for Class Com_ Study_jnilearn_accesssupermethod */  #ifndef _included_com_study_jnilearn_ Accesssupermethod   #define _included_com_study_jnilearn_accesssupermethod   #ifdef __cplusplus  extern  "C"  { Span class= "Hljs-preprocessor" > #endif  /* * class:com_study_jnilearn_ Accesssupermethod * Method:callsuperinstancemethod * Signature: () V */ jniexport voi D   Jnicall  Java_com_study_jnilearn_accesssupermethod_ Callsuperinstancemethod (jnienv *, jclass);  #ifdef __cplusplus }  #endif   #endif   

Implement the Java_com_study_jnilearn_accesssupermethod_callsuperinstancemethod function as follows:

//Accesssupermethod.c#include "com_study_jnilearn_accesssupermethod.h"JniexportvoidJnicall Java_com_study_jnilearn_accesssupermethod_callsuperinstancemethod (jnienv *env, Jclass cls) {Jclass cls_cat;    Jclass Cls_animal;    Jmethodid Mid_cat_init;    Jmethodid Mid_run;    Jmethodid Mid_getname;    Jstring C_str_name; Jobject Obj_cat;Constchar *name = NULL;// 1, get the Cat class class reference     Cls_cat = (*env)Findclass (ENV,"Com/study/jnilearn/cat");if(Cls_cat = = NULL) {return; }// 2, gets the construction method ID of the cat (the name of the constructor is unified to:<init>) Mid_cat_init = (*env)Getmethodid (env, Cls_cat,"<init>","(ljava/lang/string;) V");if(Mid_cat_init = = NULL) {return;//A constructor with only one argument string was not found}// 3, creating a String object as a parameter to the constructor method C_str_name = (*env)Newstringutf (ENV,"Tom Cat");if(C_str_name = = NULL) {return;//Failed to create string (Insufficient memory)}//  4, creating an instance of the Cat object (invoking the object's construction method and initializing the object) Obj_cat = (*env)NewObject (Env,cls_cat, mid_cat_init,c_str_name);if(Obj_cat = = NULL) {return; }//--------------5, call the Run and GetName methods of the Cat parent class animal-------------- Cls_animal = (*env)Findclass (ENV,"Com/study/jnilearn/animal");if(Cls_animal = = NULL) {return; }//Cases1: Call the Run method of the parent class Mid_run = (*env)Getmethodid (env, Cls_animal,"Run","() V");//Gets the ID of the Run method in the parent class animalif(Mid_run = = NULL) {return; }//Note: Obj_cat is an instance of cat, Cls_animal is a class reference for animal, Mid_run is a method ID in the animal class (*env)Callnonvirtualvoidmethod (env, Obj_cat, Cls_animal, Mid_run);//Cases2: Call the GetName method of the parent class//Gets the ID of the GetName method in the parent class animal Mid_getname = (*env)Getmethodid (env, Cls_animal,"GetName","() ljava/lang/string;");if(Mid_getname = = NULL) {return; } C_str_name = (*env)Callnonvirtualobjectmethod (env, Obj_cat, Cls_animal, mid_getname); Name = (*env)Getstringutfchars (env, C_str_name, NULL); printf"in C:animal Name is%s\n", name);//Frees the memory allocated by the string obtained from the Java layer (*env)Releasestringutfchars (env, c_str_name, name);quit://Delete a local reference (a subclass of Jobject or jobject is a reference variable), allowing the VM to release the resource referenced by the local variable (*env)Deletelocalref (env, CLS_CAT); (*env)Deletelocalref (env, cls_animal); (*env)Deletelocalref (env, c_str_name); (*env)Deletelocalref (env, obj_cat);}
Code explanation-Call construction method

Calling the constructor method and invoking the object's instance method is similar, passing in "< init >" As the method name to find the constructor method ID of the class, and then calling the JNI function newobject the constructor of the calling object to initialize the object. As shown in the following code:

obj_cat = (*env)->NewObject(env,cls_cat,mid_cat_init,c_str_name);

The above code calls the JNI function NewObject creates an instance object of class reference. This function does 2 things,1> create an uninitialized object and allocate memory space 2> the constructor of the calling object initializes the object. These two steps can also be separated, allocating memory for the object, and then initializing the object, as shown in the following code:

 // 1 , create an uninitialized object, and allocate memory obj_cat  =  (*env) ->  allocobject (env, CLS_CAT); if  (Obj_cat) {// 2 , invoking the object's constructor initialization object ->  callnonvirtualvoidmethod (Env,obj_cat, Cls_cat, Mid_cat_init    , c_str_name); if   ((*env)->exceptioncheck (env))  {//Check exception goto  quit ; } }

The Allocobject function creates an uninitialized object, which must be initialized by calling the constructor of the Callnonvirtualvoidmethod call object before using the object. And be very careful when you use it, make sure that the constructor is called at most once on an object. Sometimes it is useful to create an initialized object first and then call the constructor at the appropriate time. However, in most cases, you should use NewObject to avoid using error-prone Allocobject/callnonvirtualvoidmethod functions as much as possible.

Code explanation-Invoking the parent class instance method

If a method is defined in a parent class and overridden in a subclass, the instance method in the parent class can also be called. JNI provides a series of function Callnonvirtualxxxmethod to support invoking instance methods of various return value types. To invoke an instance method that is defined in the parent class, follow these steps:
1. Use the Getmethodid function to get the method ID from a class reference to the parent class

c Ls_animal  =  (*env) ->  findclass (env,  " Com/study/jnilearn/animal "); if  (Cls_animal = = NULL) {return ;} // example 1 : Call the Run method of the parent class < Span class= "Hljs-title" >mid_run  =  (*env) ->  getmethodid (env, Cls_    Animal,  "Run" ,  "() V" ); // gets the animal Idreturn ;}  

2. Pass in the subclass object, the parent class reference, the parent class method ID, and the parameter, and call Callnonvirtualvoidmethod,
One of a series of functions, such as Callnonvirtualbooleanmethod, Callnonvirtualintmethod, etc. Where callnonvirtualvoidmethod can also be used to invoke the constructor of the parent class.

// 注意:obj_cat是Cat的实例,cls_animal是Animal的Class引用,mid_run是Animal类中的方法ID(*env)->CallNonvirtualVoidMethod(env, obj_cat, cls_animal, mid_run);

In fact, in development, this kind of invocation of the parent class instance method is rarely encountered, usually in JAVA can be very simple to do: Super.func (); But some special needs may also be used, so it is necessary to know that this is the case.

Example code: Https://code.csdn.net/xyang81/jnilearn

JNI/NDK Development Guide (eight)--call constructor method and parent class instance method

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.