Java字符串可变性-java.lang.NoSuchFieldException:偏移量 [英] Java String Mutability - java.lang.NoSuchFieldException: offset

查看:129
本文介绍了Java字符串可变性-java.lang.NoSuchFieldException:偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java新手,我在此处中看到了一个问答部分.删除可变性的示例.经过测试 MutableString.java :

I'm new to Java and I saw a Q&A section here with two examples where mutability is removed. Upon testing 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

在以下方面的任何投入将不胜感激:

Any input on the following would be greatly appreciated:

a)为什么我会收到此异常
b)如何检查类中存在哪些字段(特别是Java字符串)

a) why do I get this exception
b) how do I check which fields exist in a class (Java strings specifically)

推荐答案

免责声明:这些hacks是学习和有趣琐事中的有趣课程.但是,它们绝对不是您要在任何生产代码中使用的东西.它会导致疼痛.

Disclaimer: these kinds of hacks are interesting lessons in learning and fun trivia. But they are definitely not something that you want to use in any production code. It will lead to pain.

从本质上讲,这种黑客攻击总是取决于被黑客攻击的类的实现细节.

By their very nature, such a hack always depends on implementation details of the classes that are hacked.

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

In your case you seem to be using a String implementation that doesn't have an offset field, but uses some other mechanism (or maybe just a different name!).

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

For example, I've just reviewed the Oracle Java 7 String class and it no longer has the offset field (which was used in Java 6 and earlier to share the char[] among substrings)!*

您可以使用Class.getDeclaredFields()检查此实现 定义的字段:

You can use Class.getDeclaredFields() to check which fields this implementation does define:

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

对于与Java 7兼容的该hack版本,您可以执行以下操作:

For a version of that hack that works with Java 7, you could do this:

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的内部再次更改,这也将中断.

Of course, this too will break if the internals of String change again.

* 这是一封电子邮件在谈到这种变化时,看来char[]的共享只会在某些特殊情况下提高性能.

* Here's an Email that talks about that change, it seems that the sharing of the char[] only lead to improved performance in a few, special cases.

这篇关于Java字符串可变性-java.lang.NoSuchFieldException:偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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