创建一个可变的 java.lang.String [英] Create a mutable java.lang.String
问题描述
Java String
是不可变的,这是众所周知的.自 Java 诞生以来,不可变字符串就是对 Java 的重要补充.不变性允许快速访问和大量优化,与 C 风格的字符串相比,明显更不容易出错,并有助于实施安全模型.
It's common knowledge that Java String
s are immutable. Immutable Strings are great addition to java since its inception. Immutability allows fast access and a lot of optimizations, significantly less error-prone compared to C-style strings, and helps enforce the security model.
可以在不使用黑客的情况下创建一个可变的,即
It's possible to create a mutable one without using hacks, namely
java.lang.reflect
sun.misc.Unsafe
- 引导类加载器中的类
- JNI(或 JNA,因为它需要 JNI)
但是在纯 Java 中是否有可能,以便可以随时修改字符串?问题是如何?
But is it possible in just plain Java, so that the string can be modified at any time? The question is How?
推荐答案
用Charset构造函数创建一个java.lang.String
,可以注入自己的Charset,带来自己的字符集解码器
.CharsetDecoder
在 decodeLoop 方法中获取对 CharBuffer
对象的引用.CharBuffer 包装了原始 String 对象的 char[].由于 CharsetDecoder 有对它的引用,您可以使用 CharBuffer 更改底层 char[],因此您有一个可变字符串.
Creating a java.lang.String
with the Charset constructor, one can inject your own Charset, which brings your own CharsetDecoder
. The CharsetDecoder
gets a reference to a CharBuffer
object in the decodeLoop method. The CharBuffer wraps the char[] of the original String object. Since the CharsetDecoder has a reference to it, you can change the underlying char[] using the CharBuffer, thus you have a mutable String.
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(),但我现在不在乎 :)
I don't know how to correctly implement decodeLoop(), but i don't care right now :)
这篇关于创建一个可变的 java.lang.String的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!