java字符串abcde_关于字符串的实验(abc和abcde的起始地址是否一样?)

参考网页

疑问

String是final类,也就是不可变的。

String a = “abc”;

a = “xxx”;

实际上内存中“abc”、“xxx”都没变(每次赋值实际上都开辟了新的一块内存)。只是a的引用变了。

那么有个新的疑问,如下代码

String a = “abc”;

a = “abcde”;

可以看到“abcde”内容里包含“abc”,那么“abc”会不会被复用呢?就是“abcde”、“abc”起始地址会不会一样呢,如下图这样:“abcde”取的是5个char,“abc”取的是3个char,前三个char“abc”是一样的?

a

b

c

d

e

需要实际测试一下。

试验

JDK版本

C:\Users\lenovo>java -version

java version "1.8.0_161"

Java(TM) SE Runtime Environment (build 1.8.0_161-b12)

Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

测试代码

import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class StringAddressTest {

static final Unsafe unsafe = getUnsafe();

static final boolean is64bit = true;

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InterruptedException {

String a = "abc";

String b = "abc";

String c = "abcde";

String d = "abcdefghigklmnopq";

System.out.println(a == b);

// System.out.println("======hashCode======");

// System.out.println(a.getClass() + "@" + a.hashCode());

// System.out.println(b.getClass() + "@" + b.hashCode());

// System.out.println(c.getClass() + "@" + c.hashCode());

// System.out.println(c.getClass() + "@" + d.hashCode());

//

// System.out.println("======System.identityHashCode======");

// System.out.println("a@" + System.identityHashCode(a) );

// System.out.println("b@" + System.identityHashCode(b) );

// System.out.println("c@" + System.identityHashCode(c) );

// System.out.println("d@" + System.identityHashCode(d) );

System.out.println("======Addresses======");

printAddresses("a:", a);

printAddresses("b:", b);

printAddresses("c:", c);

printAddresses("d:", d);

// TimeUnit.SECONDS.sleep(10000);

}

public static void printAddresses(String label, Object... objects) {

System.out.print(label + ": 0x");

long last = 0;

//获取偏移地址值

int offset = unsafe.arrayBaseOffset(objects.getClass());

//获取变量占用空间大小

int scale = unsafe.arrayIndexScale(objects.getClass());

switch (scale) {

case 4:

long factor = is64bit ? 8 : 1;

final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;

System.out.print(Long.toHexString(i1));

last = i1;

for (int i = 1; i < objects.length; i++) {

final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;

if (i2 > last) System.out.print(", +" + Long.toHexString(i2 - last));

else System.out.print(", -" + Long.toHexString(last - i2));

last = i2;

}

break;

case 8:

throw new AssertionError("Not supported");

}

System.out.println();

}

private static Unsafe getUnsafe() {

try {

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");

theUnsafe.setAccessible(true);

return (Unsafe) theUnsafe.get(null);

} catch (Exception e) {

throw new AssertionError(e);

}

}

}

运行结果

true

======Addresses======

a:: 0x781eea450

b:: 0x781eea450

c:: 0x781eea480

d:: 0x781eea4b8

分析1

实际测试结果可见,

String a ="abc";

String b ="abc";

出现的是同样的结果

String c ="abcde";

String d ="abcdefghigklmnopq";

都是不同的结果了。

也就是说字符串没有被复用。

分析2

请注意JDK版本,是不是别的版本也是这样的结果?不知道。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值