事情是這樣的拖云,在通過(guò)反射修改String
的final
字段的時(shí)候,出現(xiàn)該IllegalArgumentException
異常:
Field field1 = str1.getClass().getDeclaredField("value");
field1.setAccessible(true);
field1.set(str1, newStr2.toCharArray());
運(yùn)行結(jié)果是:
Exception in thread "main" java.lang.IllegalArgumentException: Can not set final [B field java.lang.String.value to [C
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:83)
at java.base/java.lang.reflect.Field.set(Field.java:778)
at com.zm.swap.twoString.Solution.swap1(Solution.java:33)
at com.zm.swap.twoString.Solution.main(Solution.java:17)
主要的報(bào)錯(cuò)提示就是這個(gè):Can not set final [B field java.lang.String.value to [C
靶庙,我覺(jué)得可能是String
的底層的value值被final
關(guān)鍵字修飾了,所以不能改娃属。因?yàn)閷?duì)Filed
類(lèi)不是很熟悉六荒,所以去網(wǎng)上找了一下相關(guān)的文章,最后仔細(xì)看了一下這個(gè)Filed
類(lèi)的set()
方法才明白是哪兒出錯(cuò)了:
因?yàn)?strong>JVM在編譯時(shí)期, 就把
final
類(lèi)型的String
進(jìn)行了優(yōu)化矾端,在編譯時(shí)期就會(huì)把String處理成常量掏击,所以無(wú)法修改類(lèi)似String str = "111111"
的值。
所以?xún)?yōu)化之后的代碼如下所示:
// 新建個(gè)類(lèi):User
User{
String name = "zm"
}
User user1 = new User();
Field field = user1.getClass().getDeclaredField("name");
field.setAccessible(true);
field.set(user1, "yw");
這里的name
屬性就是文檔中要求的聲明底層字段须床,so can be changed~