我是 Java 新手,我看到了一个问答部分 here,其中有两个示例,其中删除了可变性。在测试 MutableString.java 时:

import java.lang.reflect.Field;

public class MutableString {

    public static void main(String[] args) {
        String s = "Immutable";
        String t = "Notreally";

        mutate(s, t);
        StdOut.println(t);

        // strings are interned so this doesn't even print "Immutable" (!)
        StdOut.println("Immutable");
    }

    // change the first min(|s|, |t|) characters of s to t
    public static void mutate(String s, String t) {
        try {
            Field val = String.class.getDeclaredField("value");
            Field off = String.class.getDeclaredField("offset");
            val.setAccessible(true);
            off.setAccessible(true);
            int offset   = off.getInt(s);
            char[] value = (char[]) val.get(s);
            for (int i = 0; i < Math.min(s.length(), t.length()); i++)
                value[offset + i] = t.charAt(i);
        }
        catch (Exception e) { e.printStackTrace(); }
    }

}

我收到以下错误:
java.lang.NoSuchFieldException: offset

对以下内容的任何输入将不胜感激:

最佳答案

免责声明:这些类型的 hack 是有趣的学习类(class)和有趣的琐事。但它们绝对是 不是你想在任何生产代码中使用的东西。它会导致疼痛。

就其本质而言,此类黑客攻击始终取决于被黑客入侵的类的实现细节。

在您的情况下,您似乎正在使用没有 String 字段的 offset 实现,但使用了其他一些机制(或者可能只是不同的名称!)。

例如,我刚刚查看了 Oracle Java 7 String 类,它不再具有 offset 字段(它在 Java 6 及更早版本中用于在子字符串之间共享 char[])!*

您可以使用 Class.getDeclaredFields() 来检查此实现确实定义了哪些字段:

for (Field f : String.class.getDeclaredFields()) {
  System.out.println(f);
}

对于适用于 Java 7 的 hack 版本,您可以这样做:
public static void mutate(String s, String t) {
    try {
        Field val = String.class.getDeclaredField("value");
        val.setAccessible(true);
        char[] value = (char[]) val.get(s);
        for (int i = 0; i < Math.min(s.length(), t.length()); i++)
            value[i] = t.charAt(i);
    }
    catch (Exception e) { e.printStackTrace(); }
}

当然,如果 String 的内部结构再次更改,这也会中断。

* Here's an Email 谈到了这种变化,似乎 char[] 的共享只会在少数特殊情况下提高性能。

关于Java 字符串可变性 - java.lang.NoSuchFieldException : offset,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17489467/

10-12 00:30
查看更多