Java 原地修改字符串, how?

2022-06-14 15:54:02 +08:00
 asanelder

比如说

String s = "hallo world";

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

s = "hello world";

怎么做, 兄弟们...

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

用暴力威胁地球人

"hallo world" =√

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

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

这是出题人的问题,出题的时候考虑的是用 C 来写,后来又加上了其它的语言。C 的 char* 当然可以随便改。
你把原来的 String 转成 char[] 来做就好了,返回的时候再转回去。
这种都是算法题,不是编程语言怎么用的题。
dorothyREN
2022-06-14 21:33:12 +08:00
String s = "hallo world";
s = "hello world";
搞定
cpstar
2022-06-14 23:01:42 +08:00
反射能做到么? String 编译后,放在常量池里,类加载的时候,常量池加载到内存上,然后给一个指针到变量上,所以反射是要反射到加载到内存里的常量池么?有点类似于 C++直接搞内存?
zpxshl
2022-06-14 23:10:16 +08:00
java 级别的反射搞不定的
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
2022-06-15 10:24:40 +08:00
final 只能让 value 不指向新的对象,但通过反射光修改原对象是可行的,当然了,这样运行会报警告,不建议这么做,我只是想说实际上可以实现。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/859558

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX