JNI generic type of jobject

Discussion in 'Java' started by Philipp Kraus, Oct 4, 2011.

  1. Hello,

    I use JNI calls for some Java classes. Some Java classes are generic
    classes like:

    class mytestclass<T> {

    public native void mymethod();

    }

    The stub shows:

    JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    p_object)

    How can I get from the jobject which object type is the generic
    parameter T? Because I would
    like to create different codes if I do something like:

    mytestclass<int> x = new mytestclass<int>();
    x.mymethod();

    mytestclass<String> x = new mytestclass<String>();
    x.mymethod();

    Thanks

    Phil
     
    Philipp Kraus, Oct 4, 2011
    #1
    1. Advertising

  2. Philipp Kraus

    Silvio Guest

    On 10/04/2011 02:23 PM, Philipp Kraus wrote:
    > Hello,
    >
    > I use JNI calls for some Java classes. Some Java classes are generic
    > classes like:
    >
    > class mytestclass<T> {
    >
    > public native void mymethod();
    >
    > }
    >
    > The stub shows:
    >
    > JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    > p_object)
    >
    > How can I get from the jobject which object type is the generic
    > parameter T? Because I would
    > like to create different codes if I do something like:
    >
    > mytestclass<int> x = new mytestclass<int>();
    > x.mymethod();
    >
    > mytestclass<String> x = new mytestclass<String>();
    > x.mymethod();
    >
    > Thanks
    >
    > Phil
    >
    >


    No such thing is possible. Generics are a compile time thing. At runtime
    only the raw types are available.

    Silvio
     
    Silvio, Oct 4, 2011
    #2
    1. Advertising

  3. On 2011-10-04 14:28:14 +0200, Silvio said:

    > On 10/04/2011 02:23 PM, Philipp Kraus wrote:
    >> Hello,
    >>
    >> I use JNI calls for some Java classes. Some Java classes are generic
    >> classes like:
    >>
    >> class mytestclass<T> {
    >>
    >> public native void mymethod();
    >>
    >> }
    >>
    >> The stub shows:
    >>
    >> JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    >> p_object)
    >>
    >> How can I get from the jobject which object type is the generic
    >> parameter T? Because I would
    >> like to create different codes if I do something like:
    >>
    >> mytestclass<int> x = new mytestclass<int>();
    >> x.mymethod();
    >>
    >> mytestclass<String> x = new mytestclass<String>();
    >> x.mymethod();
    >>
    >> Thanks
    >>
    >> Phil
    >>
    >>

    >
    > No such thing is possible. Generics are a compile time thing. At
    > runtime only the raw types are available.


    Why? jobject is a pointer to the Java object that calls the JNI
    function, JNIEnv is also a pointer to the running
    environment, so I should get the type of the generic parameter, because
    the runtime / object knows them
    so within the JNI call the parameter must exists.

    I can also run in the Java class T.getClass().getName() and the Java
    code returns the name of the type
    the JNI call should do the same like JNIEnv->GetObjectClass(
    jobject.getTemplateVar(0) ) but I need
    the name / call of the "getTemplateVar(int)" function which gets an
    object to the first template parameter
    of the Java object

    Thanks

    Phil
     
    Philipp Kraus, Oct 4, 2011
    #3
  4. Philipp Kraus

    Daniel Pitts Guest

    On 10/4/11 5:28 AM, Silvio wrote:
    > On 10/04/2011 02:23 PM, Philipp Kraus wrote:
    >> Hello,
    >>
    >> I use JNI calls for some Java classes. Some Java classes are generic
    >> classes like:
    >>
    >> class mytestclass<T> {
    >>
    >> public native void mymethod();
    >>
    >> }
    >>
    >> The stub shows:
    >>
    >> JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    >> p_object)
    >>
    >> How can I get from the jobject which object type is the generic
    >> parameter T? Because I would
    >> like to create different codes if I do something like:
    >>
    >> mytestclass<int> x = new mytestclass<int>();
    >> x.mymethod();
    >>
    >> mytestclass<String> x = new mytestclass<String>();
    >> x.mymethod();
    >>
    >> Thanks
    >>
    >> Phil
    >>
    >>

    >
    > No such thing is possible. Generics are a compile time thing. At runtime
    > only the raw types are available.
    >
    > Silvio


    int is not a valid generic type parameter, as int is a primitive and
    generic types must by Object types.

    Also, generics are not the same as C++ templates. There isn't different
    code created for each concrete usage. Its all exactly the same code.

    If you are doing different behavior based on the compile time type, then
    you need to do a little bit more work to implement the strategy pattern.

    class MyTestClass<T> {
    private MyMethodStrategy<T> strategy;

    public mymethod() {
    strategy.mymethod(this);
    }
    }

    interface MyMethodStrategy<T> {
    void mymethod(MyTestClass<T> testClass);
    }


    class MyStringMethodStrategy implement MyMethodStrategy<String> {
    public native void mymethod(MyTestClass<String> testClass);
    }


    class MyIntegerMethodStrategy implement MyMethodStrategy<Integer> {
    public native void mymethod(MyTestClass<Integer> testClass);
    }


    Then you will have two different native methods to implement each strategy.
     
    Daniel Pitts, Oct 4, 2011
    #4
  5. On 2011-10-04 16:53:22 +0200, Daniel Pitts said:

    > On 10/4/11 5:28 AM, Silvio wrote:
    >> On 10/04/2011 02:23 PM, Philipp Kraus wrote:
    >>> Hello,
    >>>
    >>> I use JNI calls for some Java classes. Some Java classes are generic
    >>> classes like:
    >>>
    >>> class mytestclass<T> {
    >>>
    >>> public native void mymethod();
    >>>
    >>> }
    >>>
    >>> The stub shows:
    >>>
    >>> JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    >>> p_object)
    >>>
    >>> How can I get from the jobject which object type is the generic
    >>> parameter T? Because I would
    >>> like to create different codes if I do something like:
    >>>
    >>> mytestclass<int> x = new mytestclass<int>();
    >>> x.mymethod();
    >>>
    >>> mytestclass<String> x = new mytestclass<String>();
    >>> x.mymethod();
    >>>
    >>> Thanks
    >>>
    >>> Phil
    >>>
    >>>

    >>
    >> No such thing is possible. Generics are a compile time thing. At runtime
    >> only the raw types are available.
    >>
    >> Silvio

    >
    > int is not a valid generic type parameter, as int is a primitive and
    > generic types must by Object types.
    >
    > Also, generics are not the same as C++ templates. There isn't
    > different code created for each concrete usage. Its all exactly the
    > same code.
    >
    > If you are doing different behavior based on the compile time type,
    > then you need to do a little bit more work to implement the strategy
    > pattern.
    >
    > class MyTestClass<T> {
    > private MyMethodStrategy<T> strategy;
    >
    > public mymethod() {
    > strategy.mymethod(this);
    > }
    > }
    >
    > interface MyMethodStrategy<T> {
    > void mymethod(MyTestClass<T> testClass);
    > }
    >
    >
    > class MyStringMethodStrategy implement MyMethodStrategy<String> {
    > public native void mymethod(MyTestClass<String> testClass);
    > }
    >
    >
    > class MyIntegerMethodStrategy implement MyMethodStrategy<Integer> {
    > public native void mymethod(MyTestClass<Integer> testClass);
    > }
    >
    >
    > Then you will have two different native methods to implement each strategy.


    This a very good solution, I implement my own pattern
    Thanks
     
    Philipp Kraus, Oct 4, 2011
    #5
  6. Philipp Kraus

    Lew Guest

    Daniel Pitts wrote:
    >> Philipp Kraus wrote:
    >>> I use JNI calls for some Java classes. Some Java classes are generic
    >>> classes like:
    >>>
    >>> class mytestclass<T> {
    >>>
    >>> public native void mymethod();
    >>>
    >>> }
    >>>
    >>> The stub shows:
    >>>
    >>> JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    >>> p_object)
    >>>
    >>> How can I get from the jobject which object type is the generic
    >>> parameter T? Because I would
    >>> like to create different codes if I do something like:
    >>>
    >>> mytestclass<int> x = new mytestclass<int>();
    >>> x.mymethod();
    >>>
    >>> mytestclass<String> x = new mytestclass<String>();
    >>> x.mymethod();

    >>

    > int is not a valid generic type parameter, as int is a primitive and
    > generic types must be Object types.
    >
    > Also, generics are not the same as C++ templates. There isn't different
    > code created for each concrete usage. Its all exactly the same code.
    >
    > If you are doing different behavior based on the compile time type, then
    > you need to do a little bit more work to implement the strategy pattern.
    >
    > class MyTestClass<T> {
    > private MyMethodStrategy<T> strategy;
    >
    > public mymethod() {
    > strategy.mymethod(this);
    > }
    > }
    >
    > interface MyMethodStrategy<T> {
    > void mymethod(MyTestClass<T> testClass);
    > }
    >
    >
    > class MyStringMethodStrategy implement MyMethodStrategy<String> {
    > public native void mymethod(MyTestClass<String> testClass);
    > }
    >
    >
    > class MyIntegerMethodStrategy implement MyMethodStrategy<Integer> {
    > public native void mymethod(MyTestClass<Integer> testClass);
    > }
    >
    >
    > Then you will have two different native methods to implement each strategy.


    Kudos for a great answer!
    +1

    This pattern or ones like it are frequent and very helpful in generics programming.

    --
    Lew
     
    Lew, Oct 4, 2011
    #6
  7. Philipp Kraus

    Daniel Pitts Guest

    On 10/4/11 12:01 PM, Lew wrote:
    > Daniel Pitts wrote:
    >>> Philipp Kraus wrote:
    >>>> I use JNI calls for some Java classes. Some Java classes are generic
    >>>> classes like:
    >>>>
    >>>> class mytestclass<T> {
    >>>>
    >>>> public native void mymethod();
    >>>>
    >>>> }
    >>>>
    >>>> The stub shows:
    >>>>
    >>>> JNIEXPORT void JNICALL Java_mytestclass_mymethod(JNIEnv* p_env, jobject
    >>>> p_object)
    >>>>
    >>>> How can I get from the jobject which object type is the generic
    >>>> parameter T? Because I would
    >>>> like to create different codes if I do something like:
    >>>>
    >>>> mytestclass<int> x = new mytestclass<int>();
    >>>> x.mymethod();
    >>>>
    >>>> mytestclass<String> x = new mytestclass<String>();
    >>>> x.mymethod();
    >>>

    >> int is not a valid generic type parameter, as int is a primitive and
    >> generic types must be Object types.
    >>
    >> Also, generics are not the same as C++ templates. There isn't different
    >> code created for each concrete usage. Its all exactly the same code.
    >>
    >> If you are doing different behavior based on the compile time type, then
    >> you need to do a little bit more work to implement the strategy pattern.
    >>
    >> class MyTestClass<T> {
    >> private MyMethodStrategy<T> strategy;
    >>
    >> public mymethod() {
    >> strategy.mymethod(this);
    >> }
    >> }
    >>
    >> interface MyMethodStrategy<T> {
    >> void mymethod(MyTestClass<T> testClass);
    >> }
    >>
    >>
    >> class MyStringMethodStrategy implement MyMethodStrategy<String> {
    >> public native void mymethod(MyTestClass<String> testClass);
    >> }
    >>
    >>
    >> class MyIntegerMethodStrategy implement MyMethodStrategy<Integer> {
    >> public native void mymethod(MyTestClass<Integer> testClass);
    >> }
    >>
    >>
    >> Then you will have two different native methods to implement each strategy.

    >
    > Kudos for a great answer!
    > +1
    >
    > This pattern or ones like it are frequent and very helpful in generics programming.
    >

    They also provide greater flexibility for pluggable (user-defined)
    behavior. When applicable, I often replace protected methods with
    strategy interfaces. Especially if any two protected methods are
    independent of one another in the same class. Truth be told, I usually
    don't create protected methods at all any more, unless they are in some
    sort of adapter class for a "un-handled use-case" or some such.
     
    Daniel Pitts, Oct 4, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MP
    Replies:
    4
    Views:
    392
  2. Replies:
    10
    Views:
    7,014
  3. Vijayk
    Replies:
    12
    Views:
    7,823
    Chris Uppal
    Oct 25, 2005
  4. Tim  Wong

    C++ JNI jobject conversion

    Tim Wong, Dec 22, 2004, in forum: C++
    Replies:
    4
    Views:
    7,310
    Tim Wong
    Jan 4, 2005
  5. groupie

    jObject stays blank

    groupie, May 14, 2008, in forum: Java
    Replies:
    1
    Views:
    345
    Roedy Green
    May 15, 2008
Loading...

Share This Page