Java 原地修改字符串, how? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
asanelder
V2EX    程序员

Java 原地修改字符串, how?

  •  
      asanelder 2022-06-14 15:54:02 +08:00 3221 次点击
    这是一个创建于 1222 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如说

    String s = "hallo world";

    在不创建新的 string 下, 把 s 修改成

    s = "hello world";

    怎么做, 兄弟们...

    24 条回复    2022-06-16 00:47:10 +08:00
    chihiro2014
        1
    chihiro2014  
       2022-06-14 15:56:08 +08:00
    重新赋值
    cheng6563
        2
    cheng6563  
       2022-06-14 15:56:38 +08:00
    反射进去改 char[] value
    ianEros
        3
    ianEros  
       2022-06-14 15:57:34 +08:00
    String 是 fianl 不能干
    luckyrayyy
        4
    luckyrayyy  
       2022-06-14 16:00:23 +08:00
    反射和 unsafe
    dcsuibian
        5
    dcsuibian  
       2022-06-14 16:00:35 +08:00   1
    Java 的字符串是不可变的(优点)。
    rainboat
        6
    rainboat  
       2022-06-14 16:02:05 +08:00
    java 的 String 是不可变对象,创建一个新的 String 多简单,有啥不能这么做的理由吗?
    Kasumi20
        7
    Kasumi20  
       2022-06-14 16:04:17 +08:00
    用二进制修改器去修改.class 或者.jar 文件
    chendy
        8
    chendy  
       2022-06-14 16:11:39 +08:00
    反射进去改 value 就行
    脑筋急转弯类面试题吧,没啥实际用途
    后续问题还有给你一坨字符串,反射改了其中一个,问哪些会跟着一起改
    abc0123xyz
        9
    abc0123xyz  
       2022-06-14 16:41:14 +08:00
    指鹿为马

    用暴力威胁地球人

    "hallo world" =√

    "hello world"=×
    nothingistrue
        10
    nothingistrue  
       2022-06-14 17:03:51 +08:00
    String 是 final class + no setter ,你要想修改就只能用反射,还得是禁用安全限制的反射。虽然可以这样做,但是要做也得给其他类做,String 是可以这样设置的,强行进去修改会引起指数级的麻烦。问 String 为啥设计成不可变,都比借 String 问反射都好。
    yazinnnn
        11
    yazinnnn  
       2022-06-14 17:06:04 +08:00
    是不是你的需求有问题?
    asanelder
        12
    asanelder  
    OP
       2022-06-14 17:58:46 +08:00
    @rainboat #6
    @chendy #8
    @yazinnnn #11

    不是来自现实问题, 俺今天刷 leetcode, 要求 inplace, 所以突发这样的想法... 要是使用 char[]就好办多了
    qbqbqbqb
        13
    qbqbqbqb  
       2022-06-14 20:45:33 +08:00
    @asanelder 这种应该属于某些题目的进阶要求吧,题目里也只是说如果你用的编程语言里字符串是可变数据类型的话可以尝试 inplace 做法,不用也能通过。想达成这个目标的话用 Java, Python 这些语言是没办法的,只能换成 C++.
    ragnaroks
        14
    ragnaroks  
       2022-06-14 21:27:01 +08:00
    java 未来应该把 csharp 的 Span<T> 抄过去,到时候你再来解决这个问题即可
    CRVV
        15
    CRVV  
       2022-06-14 21:31:10 +08:00
    @asanelder

    这是出题人的问题,出题的时候考虑的是用 C 来写,后来又加上了其它的语言。C 的 char* 当然可以随便改。
    你把原来的 String 转成 char[] 来做就好了,返回的时候再转回去。
    这种都是算法题,不是编程语言怎么用的题。
    dorothyREN
        16
    dorothyREN  
       2022-06-14 21:33:12 +08:00   1
    String s = "hallo world";
    s = "hello world";
    搞定
    cpstar
        17
    cpstar  
       2022-06-14 23:01:42 +08:00
    反射能做到么? String 编译后,放在常量池里,类加载的时候,常量池加载到内存上,然后给一个指针到变量上,所以反射是要反射到加载到内存里的常量池么?有点类似于 C++直接搞内存?
    zpxshl
        18
    zpxshl  
       2022-06-14 23:10:16 +08:00 via Android
    java 级别的反射搞不定的
    Eathein
        19
    Eathein  
       2022-06-15 10:21:29 +08:00
    可以通过反射修改的,这是测试代码
    public class Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    String s = "a";
    Field value = String.class.getDeclaredField("value");
    value.setAccessible(true);
    byte[] bytes = (byte[]) value.get(s);
    bytes[0] = 66;
    System.out.println(s);//这里 s 输出的就是 66 对应的字符 B
    }
    }
    Eathein
        20
    Eathein  
       2022-06-15 10:24:40 +08:00
    final 只能让 value 不指向新的对象,但通过反射光修改原对象是可行的,当然了,这样运行会报警告,不建议这么做,我只是想说实际上可以实现。
    asanelder
        21
    asanelder  
    OP
       2022-06-15 12:23:26 +08:00
    @Eathein #19 感谢铁子提供的思路
    @CRVV #15 嗯, 这题俺感觉确实出的不太好, 解题思路和语言相关了
    lisongeee
        22
    lisongeee  
       2022-06-15 12:49:03 +08:00
    如果你的变量不是 final 的,可以考虑用 字节码插桩,编译的时候插入修改这个变量的代码,从.java 源码角度来看,确实没有创建新 string
    asanelder
        23
    asanelder  
    OP
       2022-06-15 13:10:48 +08:00
    @lisongeee #22 牛啊, 铁子, 真是脑洞大开!
    ericgui
        24
    ericgui  
       2022-06-16 00:47:10 +08:00
    @asanelder in-place 指的是不创建新的 array

    你别钻牛角尖
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2292 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 01:17 PVG 09:17 LAX 18:17 JFK 21:17
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86