众所周知,JavaString
s 是不可变的。自 java 诞生以来,不可变字符串就是它的一个重要补充。不变性允许快速访问和大量优化,与 C 样式字符串相比,显着减少出错的可能性,并有助于实施安全模型。
可以在不使用 hack 的情况下创建一个可变的,即
java.lang.reflect
sun.misc.Unsafe
- 引导类加载器中的类
- JNI(或 JNA,因为它需要 JNI)
但是,在普通的 Java 中是否有可能使字符串可以随时修改呢?问题是How?
创建一个java.lang.String
使用 Charset 构造函数,可以注入自己的 Charset,它会带来您自己的 CharsetCharsetDecoder
. The CharsetDecoder
获取对 a 的引用CharBuffer
对象在decodeLoop方法中。 CharBuffer 包装了原始 String 对象的 char[]。由于 CharsetDecoder 有对它的引用,因此您可以使用 CharBuffer 更改底层 char[],因此您有一个可变的字符串。
public class MutableStringTest {
// http://stackoverflow.com/questions/11146255/how-to-create-mutable-java-lang-string#11146288
@Test
public void testMutableString() throws Exception {
final String s = createModifiableString();
System.out.println(s);
modify(s);
System.out.println(s);
}
private final AtomicReference<CharBuffer> cbRef = new AtomicReference<CharBuffer>();
private String createModifiableString() {
Charset charset = new Charset("foo", null) {
@Override
public boolean contains(Charset cs) {
return false;
}
@Override
public CharsetDecoder newDecoder() {
CharsetDecoder cd = new CharsetDecoder(this, 1.0f, 1.0f) {
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
cbRef.set(out);
while(in.remaining()>0) {
out.append((char)in.get());
}
return CoderResult.UNDERFLOW;
}
};
return cd;
}
@Override
public CharsetEncoder newEncoder() {
return null;
}
};
return new String("abc".getBytes(), charset);
}
private void modify(String s) {
CharBuffer charBuffer = cbRef.get();
charBuffer.position(0);
charBuffer.put("xyz");
}
}
运行代码打印
abc
zzz
我不知道如何正确实现decodeLoop(),但我现在不在乎:)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)