结论:
1、直接赋值的方式,对原型模式中未深克隆的String类型属性无影响
2、反射修改原型模式中未深克隆的String类型属性,未重新赋值的所有实例中String类型属性也会发生变化;从安全的角度考虑,有被恶意破坏的风险
源码如下:
原型类
class User implements Cloneable {
private String name = "zahngsan";
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + '}';
}
}
测试类
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args)
throws CloneNotSupportedException, NoSuchFieldException, IllegalAccessException {
set();
System.out.println("========================");
fanshe();
}
// 直接赋值的方式,对原型模式中未深克隆的String类型属性无影响
private static void set() throws CloneNotSupportedException {
User user1 = new User();
User user2 = (User) user1.clone();
User user3 = (User) user1.clone();
user3.setName("lisi");
User user4 = (User) user1.clone();
System.out.println(user1); // User{name='zahngsan'}
System.out.println(user2); // User{name='zahngsan'}
System.out.println(user3); // User{name='lisi'}
System.out.println(user4); // User{name='zahngsan'}
System.out.println(user1.getName() == user2.getName()); // true
System.out.println(user1.getName() == user3.getName()); // false
System.out.println(user1.getName() == user4.getName()); // true
}
// 使用反射修改原型模式中未深克隆的String类型属性,未重新赋值的所有实例中String类型属性也会发生变化;从安全的角度考虑,有被恶意破坏的风险
private static void fanshe() throws CloneNotSupportedException, NoSuchFieldException, IllegalAccessException {
User user1 = new User();
User user2 = (User) user1.clone();
User user3 = (User) user1.clone();
String name = user3.getName();
Field value = name.getClass().getDeclaredField("value");
value.setAccessible(true);
value.set(name, new char[]{'l', 'i', 's', 'i'});
User user4 = (User) user1.clone();
System.out.println(user1); // User{name='lisi'}
System.out.println(user2); // User{name='lisi'}
System.out.println(user3); // User{name='lisi'}
System.out.println(user4); // User{name='lisi'}
System.out.println(user1.getName() == user2.getName()); // true
System.out.println(user1.getName() == user3.getName()); // true
System.out.println(user1.getName() == user4.getName()); // true
}
}