比如说
String s = "hallo world";
在不创建新的 string 下, 把 s 修改成
s = "hello world";
怎么做, 兄弟们...
1 chihiro2014 2022-06-14 15:56:08 +08:00 重新赋值 |
![]() | 2 cheng6563 2022-06-14 15:56:38 +08:00 反射进去改 char[] value |
![]() | 3 ianEros 2022-06-14 15:57:34 +08:00 String 是 fianl 不能干 |
![]() | 4 luckyrayyy 2022-06-14 16:00:23 +08:00 反射和 unsafe |
5 dcsuibian 2022-06-14 16:00:35 +08:00 ![]() Java 的字符串是不可变的(优点)。 |
6 rainboat 2022-06-14 16:02:05 +08:00 java 的 String 是不可变对象,创建一个新的 String 多简单,有啥不能这么做的理由吗? |
![]() | 7 Kasumi20 2022-06-14 16:04:17 +08:00 用二进制修改器去修改.class 或者.jar 文件 |
![]() | 8 chendy 2022-06-14 16:11:39 +08:00 反射进去改 value 就行 脑筋急转弯类面试题吧,没啥实际用途 后续问题还有给你一坨字符串,反射改了其中一个,问哪些会跟着一起改 |
![]() | 9 abc0123xyz 2022-06-14 16:41:14 +08:00 指鹿为马 用暴力威胁地球人 "hallo world" =√ "hello world"=× |
10 nothingistrue 2022-06-14 17:03:51 +08:00 String 是 final class + no setter ,你要想修改就只能用反射,还得是禁用安全限制的反射。虽然可以这样做,但是要做也得给其他类做,String 是可以这样设置的,强行进去修改会引起指数级的麻烦。问 String 为啥设计成不可变,都比借 String 问反射都好。 |
11 yazinnnn 2022-06-14 17:06:04 +08:00 是不是你的需求有问题? |
![]() | 12 asanelder OP |
13 qbqbqbqb 2022-06-14 20:45:33 +08:00 @asanelder 这种应该属于某些题目的进阶要求吧,题目里也只是说如果你用的编程语言里字符串是可变数据类型的话可以尝试 inplace 做法,不用也能通过。想达成这个目标的话用 Java, Python 这些语言是没办法的,只能换成 C++. |
![]() | 14 ragnaroks 2022-06-14 21:27:01 +08:00 java 未来应该把 csharp 的 Span<T> 抄过去,到时候你再来解决这个问题即可 |
15 CRVV 2022-06-14 21:31:10 +08:00 @asanelder 这是出题人的问题,出题的时候考虑的是用 C 来写,后来又加上了其它的语言。C 的 char* 当然可以随便改。 你把原来的 String 转成 char[] 来做就好了,返回的时候再转回去。 这种都是算法题,不是编程语言怎么用的题。 |
16 dorothyREN 2022-06-14 21:33:12 +08:00 ![]() String s = "hallo world"; s = "hello world"; 搞定 |
![]() | 17 cpstar 2022-06-14 23:01:42 +08:00 反射能做到么? String 编译后,放在常量池里,类加载的时候,常量池加载到内存上,然后给一个指针到变量上,所以反射是要反射到加载到内存里的常量池么?有点类似于 C++直接搞内存? |
18 zpxshl 2022-06-14 23:10:16 +08:00 via Android java 级别的反射搞不定的 |
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 } } |
20 Eathein 2022-06-15 10:24:40 +08:00 final 只能让 value 不指向新的对象,但通过反射光修改原对象是可行的,当然了,这样运行会报警告,不建议这么做,我只是想说实际上可以实现。 |
![]() | 21 asanelder OP |
![]() | 22 lisongeee 2022-06-15 12:49:03 +08:00 如果你的变量不是 final 的,可以考虑用 字节码插桩,编译的时候插入修改这个变量的代码,从.java 源码角度来看,确实没有创建新 string |