String(char[] value, boolean share)

1. 在观察String类的concat方法时,发现了个没见过的String构造方法

public String concat(String str) {
	int otherLen = str.length();
	if (otherLen == 0) {
		return this;
	}
	int len = value.length;
	char buf[] = Arrays.copyOf(value, len + otherLen);
	str.getChars(buf, len);
	return new String(buf, true);
}

2. 发现它传了一个true进去,点进去后

发现它对传进去的true没有做任何操作,这是一种“方法重载思想”,传一个boolean只是为了区分方法

 String(char[] value, boolean share) {
	// assert share : "unshared not supported";
	this.value = value;
}

每次new String 操作,都会赋值给final修饰的value。

3. 那么这个方法和不传boolean的有什么区别呢?

public String(char value[]) {
	this.value = Arrays.copyOf(value, value.length);
}
String(char[] value, boolean share) {
	// assert share : "unshared not supported";
	this.value = value;
}

可以观察到方法的修饰符不同,一个是public修饰符,一个是默认修饰符,也就是只有同包才能访问。所以我们是使用不了的,因为如果交给我们使用的话,可能会违反String是不可修改的原则的。

  • 例如如下代码:不能运行,只是示范

此时传入的b是引用,s的value中保存的也是b的引用,所以可以认为此时的b与String中的value是同一个对象,此时修改b[1]的值的时候,String中final修饰的value就被修改了,很明显不符合String的定义。

char [] b = {'b','c','1'};
String s = new String(b, true);
b[1] = 'a'

而直接传入char[]数组的构造方法,是调用数组拷贝,将传入的值一一赋值到String内置的value数组中,他们两个是不同的两个对象,也就保证了String类的不可修改

4. 最后我们来强行调用一下,利用反射

private static void test07() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
	char[] a = {'1','f','l'};
	Class<String> clazz = String.class;
	Constructor<String> constructor = clazz.getDeclaredConstructor(char[].class, boolean.class);
	constructor.setAccessible(true);
	String s = constructor.newInstance(a, true);
	System.out.println(s);
	//此时修改a[1]的值
	a[1]='c';
	System.out.println(s);
}

我们观察打印输出,可以发现,String对象被我们修改了

1fl

1cl

转载于:https://www.cnblogs.com/flower1360/p/13709126.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值