比如说
String s = "hallo world";
在不创建新的 string 下, 把 s 修改成
s = "hello world";
怎么做, 兄弟们...

重新赋值

反射进去改 char[] value

String 是 fianl 不能干

反射和 unsafe

Java 的字符串是不可变的(优点)。

java 的 String 是不可变对象,创建一个新的 String 多简单,有啥不能这么做的理由吗?

用二进制修改器去修改.class 或者.jar 文件

反射进去改 value 就行
脑筋急转弯类面试题吧,没啥实际用途
后续问题还有给你一坨字符串,反射改了其中一个,问哪些会跟着一起改

指鹿为马

用暴力威胁地球人

"hallo world" =√
"hello world"=×

String 是 final class + no setter ,你要想修改就只能用反射,还得是禁用安全限制的反射。虽然可以这样做,但是要做也得给其他类做,String 是可以这样设置的,强行进去修改会引起指数级的麻烦。问 String 为啥设计成不可变,都比借 String 问反射都好。

是不是你的需求有问题?

#6
#8
#11
不是来自现实问题, 俺今天刷 leetcode, 要求 inplace, 所以突发这样的想法... 要是使用 char[]就好办多了

这种应该属于某些题目的进阶要求吧,题目里也只是说如果你用的编程语言里字符串是可变数据类型的话可以尝试 inplace 做法,不用也能通过。想达成这个目标的话用 Java, Python 这些语言是没办法的,只能换成 C++.

java 未来应该把 csharp 的 Span 抄过去,到时候你再来解决这个问题即可

这是出题人的问题,出题的时候考虑的是用 C 来写,后来又加上了其它的语言。C 的 char* 当然可以随便改。
你把原来的 String 转成 char[] 来做就好了,返回的时候再转回去。
这种都是算法题,不是编程语言怎么用的题。

String s = "hallo world";
s = "hello world";
搞定

反射能做到么? String 编译后,放在常量池里,类加载的时候,常量池加载到内存上,然后给一个指针到变量上,所以反射是要反射到加载到内存里的常量池么?有点类似于 C++直接搞内存?

java 级别的反射搞不定的

可以通过反射修改的,这是测试代码
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
}
}

final 只能让 value 不指向新的对象,但通过反射光修改原对象是可行的,当然了,这样运行会报警告,不建议这么做,我只是想说实际上可以实现。

#19 感谢铁子提供的思路
#15 嗯, 这题俺感觉确实出的不太好, 解题思路和语言相关了

如果你的变量不是 final 的,可以考虑用 字节码插桩,编译的时候插入修改这个变量的代码,从.java 源码角度来看,确实没有创建新 string

#22 牛啊, 铁子, 真是脑洞大开!