在Java里,假如你要复制一个简单变量,很简单
int a=5;
int b=a;
这就完成了复制,不只是int,其他的基本类型(short,long,byte,boolean,char,float,double)都可以这样干。
不过你要是复制的是对象呢,
有两种方法:
1.实现 Cloneable 接口并重写 Object 类中的 clone()方法; 浅拷贝(shllow copy)
2.用对象的序列化和反序列化实现Serializable接口。这就是传说中的深拷贝(deep clone)
深拷贝的代码如下:
MyUtil类
package lovo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class MyUtil {
private MyUtil() {
throw new AssertionError();
}
public static <T> T clone(T obj) throws Exception {
ByteArrayOutputStream bout=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin=new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bin);
return (T) ois.readObject();
// 说明:调用 ByteArrayInputStream 或 ByteArrayOutputStream 对象的 close 方法没有任何意义 24.
// 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源
}
}
Car类
package lovo;
import java.io.Serializable;
public class Car implements Serializable{
private static final long serialVersionUID= -5713945027627603702L;
private String brand;//平拍
private int maxSpeed;//最高时速
public Car(String brand,int maxSpeed) {
this.brand=brand;
this.maxSpeed=maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
}
}
Person类
package lovo;
import java.io.Serializable;
public class Person implements Serializable{
private static final long seriaVersionUID = -9102017020286042305L;
private String name;//姓名
private int age;//年龄
private Car car;//座驾
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
}
public Person(String name, int age, Car car) {
super();
this.name = name;
this.age = age;
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
Test类
package lovo;
public class Test {
public static void main(String[] args) {
try {
Person p1=new Person("李四", 11, new Car("长城", 112));
Person p2=MyUtil.clone(p1);
p2.getCar().setBrand("大众");
p2.setAge(22);
System.out.println(p1);
System.out.println(p2);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
结果:
Person [name=李四, age=11, car=Car [brand=长城, maxSpeed=112]]Person [name=李四, age=22, car=Car [brand=大众, maxSpeed=112]]
这个时候,你给p2设置值时不会影响p1的值,浅拷贝感觉比较垃圾。那你们可以去看下这位大哥的。
https://blog.csdn.net/tounaobun/article/details/8491392#reply点击打开链接
算了我还是贴一下代码吧
A类 持久化类 里面的什么重写clone啊什么重写toString 啊之类的都是alt+shift+s 看选项搞出来的,不要自己敲代码,我最开始学代码的时候精力都花去记这些鬼东西去了。实际上都是可以用机器搞出来的,不多说,贴代码了。
package lovq;
public class A implements Cloneable{
private int number;
@Override
public String toString() {
return "[number=" + number + "]";
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
Test类
package lovq;
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
A a=new A();
a.setNumber(123456);
A b=(A) a.clone();
System.out.println("a的值"+a);
System.out.println("b的值"+b);
b.setNumber(22555);//改变b的值看一下会不会影响A的值,这才是克隆
System.out.println("a的值"+a);
System.out.println("b的值"+b);
}
}
结果:
a的值[number=123456]
b的值[number=123456]
a的值[number=123456]
b的值[number=22555]
好了,这两种方法就是java里关于复制的最核心的。有什么问题或者想交流的可以在留言区发言,我会及时回复。
下面是一些废话,可以不用看的》
还没说完,为什么要用这两种方法,用复制变量哪种方法行不行呢?当然不行。还是去看这个人的博客吧,我不想抄。我还是贴一下吧!
假设说我是一个beginner,我会这样写:
- class Student {
- private int number;
- public int getNumber() {
- return number;
- }
- public void setNumber(int number) {
- this.number = number;
- }
- }
- public class Test {
- public static void main(String args[]) {
- Student stu1 = new Student();
- stu1.setNumber(12345);
- Student stu2 = stu1;
- System.out.println("学生1:" + stu1.getNumber());
- System.out.println("学生2:" + stu2.getNumber());
- }
- }
- 学生1:12345
- 学生2:12345
这里我们自定义了一个学生类,该类只有一个number字段。
我们新建了一个学生实例,然后将该值赋值给stu2实例。(Student stu2 = stu1;)
再看看打印结果,作为一个新手,拍了拍胸腹,对象复制不过如此,
难道真的是这样吗?
我们试着改变stu2实例的number字段,再打印结果看看:
- stu2.setNumber(54321);
- System.out.println("学生1:" + stu1.getNumber());
- System.out.println("学生2:" + stu2.getNumber());
打印结果:
- 学生1:54321
- 学生2:54321
这就怪了,为什么改变学生2的学号,学生1的学号也发生了变化呢?
原因出在(stu2 = stu1) 这一句。该语句的作用是将stu1的引用赋值给stu2,
这样,stu1和stu2指向内存堆中同一个对象。如图: