加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用反射修改字符串的目的是什么?

发布时间:2020-12-15 02:07:34 所属栏目:Java 来源:网络整理
导读:我正在阅读 article,它说Java字符串不是完全不可变的.但是,在文章修改字符串的示例代码中,它调用string.toUpperCase().toCharArray(),它返回一个新字符串.那么,如果你调用toUpperCase(),那么通过更改字符串的过程是什么目的呢?这是代码: public static voi
我正在阅读 article,它说Java字符串不是完全不可变的.但是,在文章修改字符串的示例代码中,它调用string.toUpperCase().toCharArray(),它返回一个新字符串.那么,如果你调用toUpperCase(),那么通过更改字符串的过程是什么目的呢?这是代码:

public static void toUpperCase(String orig)
{
 try
 {
    Field stringValue = String.class.getDeclaredField("value");
    stringValue.setAccessible(true);
    stringValue.set(orig,orig.toUpperCase().toCharArray());
 }
 catch (Exception ex){}
}

另外,我注意到string.toUpperCase()本身不起作用.它需要是string.toUpperCase().toCharArray().是否有一个原因?

解决方法

他在做什么:

他正在获取一些他知道正确长度的字符数组(例如String的大写版本)并将其作为String的后备数组. (支持数组在String类中称为值.)

为什么他这样做:

为了说明您可以将任何char数组放在那里.

为什么这很有用:

字符串是不可变的,这允许您规避不变性.当然,不建议这样做 – 永远.相反,如果他说“请注意,因为人们可能会对您的代码执行此操作,我不会感到惊讶.即使您认为您的东西是安全的,也可能不是!”

这种影响是广泛的.不可变变量不再是不可变的.最终变量不再是最终的.线程安全对象不再是线程安全的.您认为可以依赖的合同,您不能再这样做了.所有这些都是因为某个工程师在某个地方遇到了问题,他无法用正常手段修复,所以他深入研究解决问题.不要’那个家伙’.

您还将注意到现在如何更改该String的hashCode.所以,如果你从未计算过该String的hashCode,它仍然为0,所以你没事.另一方面,如果你已经计算了它,当你把它放在HashMap或HashSet中时,它将不会被检索.

考虑以下:

import java.util.*;
import java.lang.reflect.*;

class HashTest {        

    /** Results:
     C:Documents and SettingsglowcoderMy Documents>java HashTest
        Orig hash: -804322678
        New value: STACKOVERFLOW
        Contains orig: true
        Contains copy: false
     */

    public static void main(String[] args) throws Exception {

        Set<String> set = new HashSet<String>();
        String str = "StackOverflow";
        System.out.println("Orig hash: " + str.hashCode());
        set.add(str);

        Field stringValue = String.class.getDeclaredField("value");
        stringValue.setAccessible(true);
        stringValue.set(str,str.toUpperCase().toCharArray()); // 

        System.out.println("New value: " + str);

        String copy = new String(str); // force a copy
        System.out.println("Contains orig: " + set.contains(str));
        System.out.println("Contains copy: " + set.contains(copy));
    }

}

我敢打赌他这样做是为了警告不良行为,而不是表现出“酷”的伎俩.

编辑:我找到了你所指的文章,以及它所基于的文章.最初的文章指出:“这意味着如果另一个包中的类”摆弄“一个实习字符串,它会对你的程序造成严重破坏.这是件好事吗?(你不需要回答;-)”我我认为这很清楚这是一个保护指南而不是如何编码的建议.

因此,如果你只用一条信息离开这个线程,那就是反射是危险的,不可靠的,而且不容小觑!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读