2011-07-18 65 views
0

我正在使用具有方法「getName()」的特定API。 getName()返回一個字符串。是否有可能修改該字符串? API中沒有包含修飾符方法,並且String getName()返回的是私有的。我無法修改API。修改/設置從訪問器方法返回的字符串

+0

嗨@Ashtheking,歡迎來到堆棧溢出。當標籤中已經存在標籤時,您不需要將語言放在標題中,所以我已經爲您提前編輯問題標題。希望沒關係:-) –

+1

請參閱cularis關於你的問題的答案,但也要考慮如果API沒有提供修改價值的方法,那麼他們可能不希望你這樣做。 –

回答

0

相反,普遍認爲,這是可能改變在JDK版本1.5和更新一個String對象的內容,但我(也可能是其他人在這裏)強烈反對這樣做的原因有很多。字符串從來沒有被改變的意思,它們也不是爲它而建,意味着任何嘗試這樣做都會很快變得相當混亂。也就是說,如果你需要它作爲一個絕對不得已,否則世界將要結束之類的話,這裏有一個最基本的方式來做到這一點:

public static void main(String[] args) throws Exception { 
    String foo = "foo"; 
    System.out.println("foo's hash value: " + foo.hashCode()); 
    Field stringValueField = String.class.getDeclaredField("value"); 
    stringValueField.setAccessible(true); 
    stringValueField.set(foo, "bar".toCharArray()); 
    Field stringHashField = String.class.getDeclaredField("hash"); 
    stringHashField.setAccessible(true); 
    stringHashField.set(foo, 0); 
    System.out.println("foo's new value: " + foo); 
    System.out.println("foo's new hash value: " + foo.hashCode()); 
} 

請仔細記錄,然而,其他的字符串中的字段:偏移量和計數。您也必須處理這些字段,具體取決於您如何更改字符串的值。最後,也許最重要的是,你必須考慮如果你修改interned String會發生什麼。

+0

謝謝。如果這是世界末日的糟糕,我不認爲我會使用它。我認爲這也可能導致問題,因爲該方法是針對連接到服務器的客戶端的用戶名。 – Ashtheking

3

編號字符串是不可變的。如果API中沒有setter,則不能更改name的內容。

1

字符串在Java語言中是不可變的,這意味着不可能修改任何String對象。 (所有看似修改字符串的String方法,如concatappend,其實只是創建並返回一個新的String,離開舊不變。)

如果您需要修改String本地,你可以在本地參考上使用連接或替換。如果您需要修改getName()將會返回的String,恐怕您運氣不佳。

0

關於您希望使用特定API中的X.getName()的代碼,您可以使用使用X.getName()在Y.getName()中執行所有更改的代理類Y.如果有一天特定的API發生變化(只需更改一個地方),就可以輕鬆實現。

要在特定API中更改X.getName()行爲,可以在運行時使用一些字節碼操作(例如http://www.csg.is.titech.ac.jp/~chiba/javassist/)。 但是這應該是絕對最後的資源。

0

它可能是getName()返回一個字段的值,稱爲name在這種情況下,您可以使用反射來更改它。