我正在使用具有“getName()”方法的特定API。 getName()返回一个字符串。是否可以修改该字符串? API中不包含修饰符方法,并且String getName()返回为private。我无法修改API。
答案 0 :(得分:3)
没有。字符串是不可变的。如果API中没有setter,则无法更改name
的内容。
答案 1 :(得分:1)
字符串在Java语言中是不可变的,这意味着无法修改任何String
对象。 (似乎修改字符串的所有String方法,例如concat
和append
,实际上只是创建并返回一个新的String
并保持原来的不变。)
如果您需要在本地修改String
,则可以在本地参考上使用连接或替换。如果您需要修改String
将返回的getName()
,我担心您运气不好。
答案 2 :(得分:0)
关于您希望在特定API中使用X.getName()的任何地方的代码,您可以使用代理类Y,它使用X.getName()在Y.getName()中进行所有更改。如果有一天特定的API发生变化(您只需要更改一个地方),这就很容易了。
要在特定API中更改X.getName()行为,您可以在运行时使用一些字节码操作(例如http://www.csg.is.titech.ac.jp/~chiba/javassist/)。 但这应该是绝对的最后资源。
答案 3 :(得分:0)
getName()可能会返回名为name
的字段的值。在这种情况下,您可以使用反射来更改它。
答案 4 :(得分: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());
}
但请注意String中的其他字段:offset和count。您还必须处理这些字段,具体取决于您更改字符串值的方式。最后,也许最重要的是,您必须考虑修改interned String时会发生什么。