Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果尝试使用反射将值设置为String类的value[]字段,Java6和Java7会产生不同的结果_Java_String_Reflection_Java 7_Java 6 - Fatal编程技术网

如果尝试使用反射将值设置为String类的value[]字段,Java6和Java7会产生不同的结果

如果尝试使用反射将值设置为String类的value[]字段,Java6和Java7会产生不同的结果,java,string,reflection,java-7,java-6,Java,String,Reflection,Java 7,Java 6,下面的代码尝试使用Java 7将值设置为String类的私有最终字符值[]字段 package test; import java.lang.reflect.Field; public final class Test { static { try { Field value = String.class.getDeclaredField("value"); value.setAccessibl

下面的代码尝试使用Java 7将值设置为String类
私有最终字符值[]
字段

package test;

import java.lang.reflect.Field;

public final class Test 
{
    static
    {
        try
        {
            Field value = String.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set("Hello World", value.get("1234567890"));
        }
        catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e)
        {
            System.out.println(e.toString());
        }
    }

    public static void main(String[] args) 
    {
        System.out.println("Hello World");
    }
}
它会在控制台上无声地显示
1234567890
,这是毫无疑问的


当我尝试使用Java 6做同样的事情时,如下所示

package test;

import java.lang.reflect.Field;

public final class Test
{
    static
    {
        try
        {
            Field value = String.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set("Hello World", value.get("1234567890"));
        }
        catch (IllegalArgumentException e)
        {
            System.out.println(e.toString());
        }
        catch (IllegalAccessException e)
        {
            System.out.println(e.toString());
        }
        catch (NoSuchFieldException e)
        {
            System.out.println(e.toString());
        }
        catch (SecurityException e)
        {
            System.out.println(e.toString());
        }
    }
    public static void main(String[] args)
    {
        System.out.println("Hello World");
    }
}
它导致引发以下异常

线程“main”java.lang.ArrayIndexOutOfBoundsException中出现异常

当语句
value.set(“Hello World”,value.get(“1234567890”))中
value.get(“1234567890”)的长度为
大于或等于字符串
Hello World

比如说,

如果出现以下语句(如前面的代码段所示)

替换为以下内容

value.set("Hello World", value.get("12345678901"));
那么,当
set()
方法的第二个参数的长度小于第一个参数时,为什么不使用Java6(或者可能更低,我没有尝试过)呢

顺便说一句,我可以理解以这种方式处理带有反射的私有字段是不推荐的,而且是最糟糕的

那么,当set()方法的第二个参数的长度小于第一个参数时,为什么Java 6(或者可能更低,我没有尝试过)不能实现这一点呢

在Java 6中,您正设法将
字符数组设置为新引用,但您没有更改其他字段,这些字段指定字符串引用的
char[]
部分

我记不起确切的字段名,但它是这样的:

char[] value;
int offset;
int count;
因此,对于“覆盖”整个字符数组的字符串,
offset
将为0,
count
将为
value.length
。现在,如果用较短的
字符[]
替换
,但不更改
计数
,则
偏移量+计数
超出了数组的末尾。。。它在数组的边界之外。这样做的目的是,像
substring
这样的操作不需要复制字符数据-它们只创建一个引用现有数组的新对象,具有不同的偏移/计数值

在Java7中,从更新5开始,字符串没有这个偏移量/计数概念;相反,每个字符串都有自己的字符数组,并且起始和结束都是隐式的。我想这就是为什么它在Java7中适用的原因

char[] value;
int offset;
int count;