2011-10-17 62 views
1

我有一個Java方法是這樣的JNI - 如何從C++調用Java方法時修改參數?

public boolean ReadBool(String ValueName, Boolean Value) 
{ 
    boolean Retval = ...; 
    ... 
    Value = true; 
    ... 
    return bRetval; 
} 

,我從原生代碼(C++)稱這樣的:

jMethodID MethodId = pEnv->GetMethodID(ClassId, "ReadBool", "(Ljava/lang/String;Ljava/lang/Boolean;)Z"); 
// What goes instead of "??" ? 
bool bOk = pEnv->CallBooleanMethod(myobject, MethodId, pEnv->NewStringUTF("Value1"), "??"); 

我的目的是Java方法「迴歸」一個布爾值在價值。我明白一個內置的布爾值不適用於此目的。是否有可能用布爾包裝來做到這一點?如何構造對象來代替「??」 ?

我已經搜索了一下,但仍有一些問題。例如,我想我可以傳遞一個通過調用布爾的< init「>」方法創建的對象。但是,Java ReadBool中的賦值不會引用新創建的包裝器,並拋棄第一個對象?在這種情況下,我會打電話給<init>。我認爲應該可以創建(在本機代碼中)Java認爲是空的對象,其類型爲布爾值。那可能嗎?或者我完全在錯誤的軌道上?

回答

2

布爾在Java不變的,所以你需要自己的包裝類,它可以是很簡單的,但:

public class BooleanWrapper { 
    public boolean val; 
    // public is fine here imo, but you can obviously use [g|s]etters as well 
} 

或者,如果你不希望這樣,我們可以使用一個..這不是真的很漂亮,但很高興知道破解:打電話時

public void hack(boolean[] vals) { 
    vals[0] = true; // voila, now you change the value itself 
} 

具有一些明顯的缺點(和看起來很奇怪),但如果你是罰款保持特定的參數序列,你可以這樣做:

public void hack(boolean.. vals) { 
    vals[0] = true; // voila, now you change the value itself 
} 

那種方式來電者不必使用像new boolean[] {}這樣的東西;你可以明顯地欺騙和改變布爾對象本身的內部狀態,但這會產生不必要的後果(如果你在內部改變Boolean.TRUE實例爲false,這會得到有趣的結果,所以布爾值被緩存)。所以不要這樣做。

+0

布爾是不可變的 - 這是否意味着當一個布爾值作爲參數傳遞時,該方法不能改變它?我想到Value(ReadBool的參數)是一個引用,並且ReadBool中的賦值將構造一個新的布爾值,然後Value將引用該值。它不是這樣嗎? (對不起,要求這樣的基本的東西,但我是新來的Java ;-) – Dabbler

+0

是的,你對不可改變的解釋是正確的。最好始終使用不可變類(無論如何可能),並使用返回值作爲結果。如果你有多個相關的返回值,那麼爲它們創建一個對象 - 如果你有多個不相關的返回值,那麼使你的方法更加具體。 –

+0

這是真的;我驗證它如下:void TestCall(Boolean b){b = false; },然後調用Boolean bTest = true; TESTCALL(BTEST); b的值實際上是在TestCall中修改的,我知道正在創建一個新的布爾值,然後引用b。但是bTest怎麼樣仍然是真的 - 不b和bTest是指同一個布爾值? – Dabbler