数据类型
Java的数据类型包括基本数据类型和引用数据类型:
基本数据类型:
-
整形:byte, short, int, long
-
浮点型:float, double
-
字符型:char
-
布尔型:boolean
引用数据类型:class, interface, array。
引用拷贝,浅拷贝,深拷贝
引用拷贝
在Java中,对象的引用拷贝是指将一个对象的引用赋值给另一个变量。通过引用拷贝,两个变量将指向同一个对象,它们共享同一块内存空间。当修改其中一个变量指向的对象时,另一个变量也会受到影响。
下面是一个简单的示例代码,演示了对象引用拷贝的概念:
public class Test {
public static void main(String[] args) {
// 创建一个Person对象
Person person1 = new Person("Alice", 25);
// 将person1的引用拷贝给person2
Person person2 = person1;
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
// 修改person1的属性
person1.setName("Bob");
person1.setAge(30);
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
// True
System.out.println(person1 == person2);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person[name=" + name + ", age=" + age + "]";
}
}
在上述代码中,创建了一个Person对象person1,然后将其引用拷贝给person2。修改person1的属性后,打印person1和person2的值,可以发现它们指向同一个对象,因此修改person1的属性后,person2的属性也会相应改变。
输出结果如下:
person1: Person[name=Alice, age=25]
person2: Person[name=Alice, age=25]
person1: Person[name=Bob, age=30]
person2: Person[name=Bob, age=30]
true
可以看到,通过引用拷贝,person1和person2指向同一个Person对象,修改其中一个对象的属性会影响另一个对象。
浅拷贝
在Java中,浅拷贝(Shallow Copy)是指创建一个新对象,并将原始对象中的所有字段的值复制到新对象中。浅拷贝只是简单地复制对象的字段值,如果对象中包含引用类型的字段,则新对象和原始对象会共享这些引用类型的字段。
浅拷贝是通过复制对象的引用来实现的,也就是说,新对象和原始对象指向了同一个内存地址。因此,如果修改了新对象的引用类型字段的值,原始对象的引用类型字段的值也会被修改,因为它们指向同一个对象。
要实现浅拷贝,可以使用以下几种方式:
使用Object类的clone()
方法:Object类中的clone()方法可以复制一个对象,但它只复制对象的字段值,不复制引用类型字段指向的对象。因此,如果对象中包含引用类型字段,那么新对象和原始对象会共享这些引用类型的字段。
使用拷贝构造函数:通过定义一个构造函数,参数为原始对象,将原始对象中的字段值复制到新对象中。
需要注意的是,浅拷贝只是复制对象的字段值,而不复制对象内部的引用类型字段的值。因此,如果需要实现深拷贝,就需要对引用类型字段进行递归拷贝,确保新对象和原始对象的引用类型字段指向不同的对象。
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Address(String address) {
this.address = address;
}
}
class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Address getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return this.name + "-" + this.age + "-" + this.address.getAddress();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Address address1 = new Address("山东");
Person person1 = new Person("Alice", 25, address1);
Person person2 = (Person) person1.clone();
System.out.println(person1);
System.out.println(person2);
person1.setAge(30);
address1.setAddress("上海");
System.out.println(person1);
System.out.println(person2);
//Alice-25-山东
//Alice-25-山东
//Alice-30-上海
//Alice-25-上海
}
}
深拷贝
在 Java 中,深拷贝(Deep Copy)是指创建一个新对象,将原始对象中的所有字段的值都复制到新对象中。深拷贝会递归复制对象的所有层级,包括对象的引用类型字段,确保新对象和原始对象完全独立相对地,浅拷贝(Shallow Copy)只是简单地复制对象的字段值,如果对象中包含引用类型的字段,那么新对象和原始对象会共享这些引用类型的字段。
为了实现深拷贝,可以使用以下几种方式:
实现 Cloneable接口和覆写 clone() 方法
:通过实现 Cloneable 接口来指明对象可以进行拷贝操作,并覆写 clone() 方法来实现深拷贝的逻辑。
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("Alice", 25, new Address("山东"));
Person person2 = (Person) person1.clone();
System.out.println(person1);
System.out.println(person2);
person2.setName("david");
person2.setAge(30);
person2.getAddress().setAddress("上海");
System.out.println(person1);
System.out.println(person2);
//Alice-25-山东
//Alice-25-山东
//Alice-25-山东
//david-30-上海
}
}
public class Address implements Cloneable{
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Address(String address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Address clone = (Address) super.clone();
clone.setAddress(this.address);
return clone;
}
}
class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public Person() {
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Address getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return this.name + "-" + this.age + "-" + this.address.getAddress();
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person res = (Person) super.clone();
res.address = (Address) this.address.clone();
return res;
}
}
使用序列化和反序列化:通过将对象序列化为字流,再将字节流反序列化为新对象来实现深拷贝。
public class MyClass implements Serializable {
private int value;
private MyObject obj;
// 构造函数和其他方法
public MyClass deepCopy() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this); // 序列化当前对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (MyClass) ois.readObject(); // 反序列化生成新对象
}
}
需要注意的是,为了现深拷贝,不仅仅需要拷贝对象本身,还需要拷贝对象内部的引用类型字段。因此,如果引用类型字段也需要支持深拷贝,那么该引用类型也需要实现 Cloneable 接口或者序列化接口,并在拷贝方法中进行递归拷。
浅拷贝和深拷贝的区别
在Java中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象拷贝方式,它们的主要区别如下:
- 复制的内容不同:
- 浅拷贝只复制对象的字段值,不复制引用类型字段指向的对象。
- 深拷贝会递归复制对象的所有层级,包括对象的引用类型字段。
- 对象的独立性不同:
- 浅拷贝复制后的对象与原始对象共享相同的引用类型字段,即它们指向相同的对象。
- 深拷贝复制后的对象与原始对象完全独立,它们的引用类型字段指向不同的对象。
- 对象修改的影响不同:
- 浅拷贝中,如果修改新对象的引用类型字段的值,原始对象的相应字段也会被修改,因为它们指向同一个对象。
- 深拷贝中,修改新对象的引用类型字段的值不会影响原始对象的相应字段,因为它们指向不同的对象。
- 实现方式不同:
- 浅拷贝可以通过
Object类的clone()
方法、拷贝构造函数等方式实现。 - 深拷贝需要对对象的引用类型字段进行递归拷贝,可以通过实现Cloneable接口和覆盖clone()方法、使用序列化和反序列化等方式实现。
- 浅拷贝可以通过
总结来说,浅拷贝只复制对象的字段值,不复制引用类型字段指向的对象,而深拷贝会递归复制所有层级的对象,确保新对象和原始对象完全独立。因此,深拷贝相比浅拷贝更加安全,但也需要更多的资源和性能开销。选择使用哪种拷贝方式,需要根据具体的场景和需求来决定。
标签:Java,name,对象,age,基础,address,拷贝,public From: https://www.cnblogs.com/DCFV/p/18292608