创建一个可变的java.lang.String [英] Create a mutable java.lang.String
问题描述
众所周知,Java String
是不可变的。从一开始,不可变字符串就是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
- bootstrap类加载器中的类
- JNI(或JNA,因为它需要JNI)
java.lang.reflect
sun.misc.Unsafe
- Classes in bootstrap classloader
- JNI (or JNA as it requires JNI)
但它是否可能只是普通的Java,所以字符串可以修改为随时?问题是如何?
But is it possible in just plain Java, so that the string can be modified at any time? The question is How?
推荐答案
创建 java.lang.String
使用Charset构造函数,可以注入自己的Charset,它带来你自己的 CharsetDecoder
。 CharsetDecoder
在decodeLoop方法中获取对 CharBuffer
对象的引用。 CharBuffer包装原始String对象的char []。由于CharsetDecoder具有对它的引用,您可以使用CharBuffer更改底层char [],因此您有一个可变的String。
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屋!