创建一个可变的 java.lang.String [英] Create a mutable java.lang.String

查看:26
本文介绍了创建一个可变的 java.lang.String的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java String 是不可变的,这是众所周知的.自 Java 诞生以来,不可变字符串就是对 Java 的重要补充.不变性允许快速访问和大量优化,与 C 风格的字符串相比,明显更不容易出错,并有助于实施安全模型.

It's common knowledge that Java Strings 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆