修改/设置从Accessor方法返回的字符串

时间:2011-07-18 14:01:08

标签: java string

我正在使用具有“getName()”方法的特定API。 getName()返回一个字符串。是否可以修改该字符串? API中不包含修饰符方法,并且String getName()返回为private。我无法修改API。

5 个答案:

答案 0 :(得分:3)

没有。字符串是不可变的。如果API中没有setter,则无法更改name的内容。

答案 1 :(得分:1)

字符串在Java语言中是不可变的,这意味着无法修改任何String对象。 (似乎修改字符串的所有String方法,例如concatappend,实际上只是创建并返回一个新的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时会发生什么。