• java复制的两种方式


    在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,我会这样写:

    [java] view plain copy
    1. class Student {  
    2.     private int number;  
    3.   
    4.     public int getNumber() {  
    5.         return number;  
    6.     }  
    7.   
    8.     public void setNumber(int number) {  
    9.         this.number = number;  
    10.     }  
    11.       
    12. }  
    13. public class Test {  
    14.       
    15.     public static void main(String args[]) {  
    16.           
    17.         Student stu1 = new Student();  
    18.         stu1.setNumber(12345);  
    19.         Student stu2 = stu1;  
    20.           
    21.         System.out.println("学生1:" + stu1.getNumber());  
    22.         System.out.println("学生2:" + stu2.getNumber());  
    23.     }  
    24. }  


    打印结果:

    [plain] view plain copy
    1. 学生1:12345  
    2. 学生2:12345  

    这里我们自定义了一个学生类,该类只有一个number字段。

    我们新建了一个学生实例,然后将该值赋值给stu2实例。(Student stu2 = stu1;)

    再看看打印结果,作为一个新手,拍了拍胸腹,对象复制不过如此,

    难道真的是这样吗?


    我们试着改变stu2实例的number字段,再打印结果看看:

    [java] view plain copy
    1. stu2.setNumber(54321);  
    2.   
    3. System.out.println("学生1:" + stu1.getNumber());  
    4. System.out.println("学生2:" + stu2.getNumber());  

    打印结果:

    [plain] view plain copy
    1. 学生1:54321  
    2. 学生2:54321  

    这就怪了,为什么改变学生2的学号,学生1的学号也发生了变化呢?


    原因出在(stu2 = stu1) 这一句。该语句的作用是将stu1的引用赋值给stu2,

    这样,stu1和stu2指向内存堆中同一个对象。如图:




  • 相关阅读:
    线程的start和run方法的区别
    GC相关的面试题
    AVR单片机教程——EasyElectronics Library v1.3手册
    我回来了
    继续停更通知
    停更通知
    玩玩24点(上)
    AVR单片机教程——EasyElectronics Library v1.2手册
    AVR单片机教程——数码管
    算法基础课程总结
  • 原文地址:https://www.cnblogs.com/Z2978/p/12805885.html
Copyright © 2020-2023  润新知