2010-03-22 60 views
4

我們如何在JNI中新建基元類型。我有一個返回jobject的函數。它可能返回jintjcharJNI新的基元類型

NewString,爲什麼不NewIntegerNewCharacterNewDouble,等有一個在目前JNI層沒有自動裝箱。

我可以使用NewObject調用,但是這會對創建原始類型造成太大的開銷。

jobject NewInteger(JNIEnv* env, jint value) 
{ 
    jclass cls = FindClass(env, "java/lang/Integer"); 
    jmethodID methodID = GetMethodID(env, cls, "<init>", "(I)V", false); 
    return env->NewObject(cls, methodID, value); 
} 

我有包裝函數來獲取Class和MethodID。

+0

@Firat - 如果你已經開始擔心這種事情,這表示你的應用程序有太多的JNI *。 – 2010-03-22 22:46:29

+1

我們的Java API使用C代碼。一切都依賴於JNI調用的性能。這就是爲什麼我儘可能快地做出這一部分的原因。 – Firat 2010-03-23 00:01:06

回答

7

jint,jdouble等不等於jobjects。正如你所說,它們是原始變量。只需填寫他們!

jint someInt = 1; 
jdouble someDouble = 3.14159; 

重新編輯:我明白了,你想回到盒裝類型,如IntegerDouble,等呀,你貼的包裝函數可能是要走的路。

+0

我知道他們不是工作類型。但是有沒有更好的方法來創建jobject,而不是通過NewObject路由? JNI具有NewString,但不包含其他原始類型的NewXXX調用。 – Firat 2010-03-22 21:25:13

+1

@Firat:我有一種「更好」的方式,即調用盒裝類型的'valueOf'方法,但這實際上只是調用工廠方法,在功能上與使用'NewObject'沒有區別。 :-P – 2010-03-22 21:27:50

+0

我認爲這可能是一個更好的主意,但是valueOf以String作爲參數。我需要NewString,並調用靜態函數。 – Firat 2010-03-22 21:53:03

1

你爲什麼覺得這種方法「太多開銷」?如果你想返回一個盒裝值(這是一個包含一個基元的對象,而不是一個「原始類型」),那麼你需要創建該對象。

一種替代方法是在包裝類型上調用valueOf()方法。

但是,我認爲最好是返回實際的原始值,並讓它在Java端處於盒裝狀態(如果需要的話)。


如果您擔心函數/構造函數查找的開銷,那麼您應該緩存方法ID。與對象指針不同,它們不會改變(有些注意事項是卸載不適用於原始包裝的類)。在這裏可以看到第10.7項:http://java.sun.com/docs/books/jni/html/pitfalls.html

+0

我認爲OP正試圖實現一個需要盒裝對象返回的接口;缺少改變界面,你無法直接返回原語。 – 2010-03-22 21:32:47

+0

該操作需要返回jobject類型。它類似於Map.put(key,value),它返回一個Object,如果它存在類似的鍵。 開銷是每次我需要找到類,得到methodId。可以緩存它們以改善它,但如果JNI接口具有這些功能,那將會很好。 – Firat 2010-03-22 21:38:44