当前位置: 首页 > 面试题库 >

创建一个可变的java.lang.String

阮桐
2023-03-14
问题内容

众所周知,Java
String是不可变的。自从成立以来,不可变字符串是Java的重要补充。不变性允许快速访问和大量优化,与C风格的字符串相比,不易出错,并有助于加强安全性模型。

无需使用骇客就可以创建一个可变的对象,即

  • java.lang.reflect
  • sun.misc.Unsafe
  • 引导类加载器中的类
  • JNI(或JNA,因为它需要JNI)

但是有可能仅使用普通Java,以便可以随时修改字符串吗?问题是 如何


问题答案:

java.lang.String使用Charset构造函数创建一个,可以注入自己的Charset,从而带来自己的CharsetDecoder。的CharsetDecoder到达一个基准CharBuffer在decodeLoop方法对象。CharBuffer包装原始String对象的char
[]。由于CharsetDecoder具有对其的引用,因此您可以使用CharBuffer更改基础char [],因此您具有可变的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(),但是我现在不在乎:)



 类似资料:
  • 我实现了一个可撤消的JTextField,问题是当我创建多个JTextField时,它只是撤消创建的最后一个实例。代码如下-要复制,请在第三个字段中输入一些文本,然后在第一个文本字段中输入一些代码并键入ctrl-z以撤消-它只从第三个文本字段中删除文本。有人能看到我做错了什么吗?

  • 我目前正在与tkinter一起完成一项学校作业,为用户创建一个图形用户界面以输入他们的输入。我决定将输入分成不同的页面,以避免用户被问题淹没,并且不需要滚动 每一页都有一系列标签和条目,在一个右除数和一个左除数上分开,我已经设法在每一页上实现了这一点,付出了一些努力。这是我工作代码的简化版本: 然而,在将每个页面拆分为两个不同的Frame()容器时,我遇到了两个问题: 用ipadx和ipady设置

  • 问题内容: 我想用Python(不是数组)中的一个创建10个变量。像这样: 我想创建的变量名,在这种情况下: ,,,…, 我不想一个数组 我有一个坐标图(640 x 480)。我正在确定像素颜色为白色的坐标。地面上有3个球,我想获取每个球的中心坐标,因此,如果要评估的坐标距离最后一个球很近,则x和y坐标将被平均(如果该坐标属于a)新球的坐标将属于新坐标组。 问题答案: 您不应该这样做,但是如果您真

  • 问题内容: 我正在尝试将十六进制值转换为int,以便创建新的可绘制颜色。我不确定是否可以,但是根据文档,应该可以。它明确地要求 公共ColorDrawable(int颜色) 在API级别1中添加。创建具有指定颜色的新ColorDrawable。 参数 color 绘制的颜色。 因此,我的代码无法正常工作,因为我收到一个无效的int:“ FF6666”错误。有任何想法吗? 问题答案: 因为您在谈论十

  • 当你使用了一个未知的变量名,通常 JavaScript 会自动创建全局变量: function f() { foo = 123 } f() foo 123 好在你会在 ECMAScript5 的严谨模式得到警告[1]: function f() { 'use strict'; foo = 123 } f() ReferenceError: foo is not defined 参考 [1] Jav