java数组的对象化,序列化以及拷贝
来源:互联网 发布:王者荣耀淘宝代充原理 编辑:程序博客网 时间:2024/05/17 07:40
本篇将介绍数组的一些特殊的特性,跟C语言的数组相比,java赋予了数组新的面向对象的性质,比如数组即对象,数组的序列化,数组的拷贝,这也为数组的拷贝提供了新的优雅的方案。
package com.zd.test.java.ds;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;public class ArrayTest { public static void main(String[] args) throws Exception { // 1.数组和泛型 int[] data = new int[] { 1, 2, 3 }; /* List<int[]> asList = Arrays.asList(data); for (int is[] : asList) { System.out.println(is); } */ asList(data); System.out.println("-----------------------"); asList(new String[] { "A", "B", "C" }); System.out.println("-----------------------"); test("zhangsan", data); System.out.println("-----------------------"); // 此时new char[]{'A','B','C'}为一个char[]数组对象,可以看一下类型 char[] cdata = new char[] { 'A', 'B', 'C' }; asList(cdata); System.out.println("类名:" + cdata.getClass().getCanonicalName()); System.out.println("父类:" + cdata.getClass().getSuperclass().getCanonicalName()); Class<?>[] interfaces = cdata.getClass().getInterfaces(); System.out.println("实现的接口:"); for (Class<?> class1 : interfaces) { System.out.println(class1.getCanonicalName()); } /** * 类名:char[] 父类:java.lang.Object 实现的接口: java.lang.Cloneable * java.io.Serializable * 可以看出其父类是java.lang.Object,实现了Cloneable和Serializable接口,数组是可复制和可序列化的。 */ // 2.数组的拷贝 Person[] ps = new Person[] { new Person("1", 1), new Person("2", 2) }; Person[] persons = ps.clone(); persons[0].name = "3";// 改变拷贝对象的属性值 // 结果是原来对象的属性值也被改变了,数组的拷贝是浅拷贝,它拷贝的元素的地址,如果是对象元素,只拷贝对象地址,是浅拷贝 System.out.println("before:" + ps[0].name); // 深拷贝的例子,Man对象,需要实现Cloneable接口 Man m = new Man("1", 1); Man m1 = (Man) m.clone(); m1.name = "3";// 改变拷贝对象的属性值 System.out.println("before : " + m.name); // 对象的每一个值都改变了 // 对象的序列化 Dog dog = new Dog("旺旺", 2); Dog dog2 = dog.deepCopy(); System.out.println("dog : " + dog + ", name : " + dog.name + ", age : " + dog.age); System.out.println("dog2 : " + dog2 + ", name : " + dog2.name + ", age : " + dog2.age); // dog : com.zd.test.java.ds.ArrayTest$Dog@29ba92bb, name : 旺旺, age : 2 // dog2 : com.zd.test.java.ds.ArrayTest$Dog@343abc87, name : 旺旺, age : 2 // 从上面的实例化的例子可以看出来,其实可以利用序列化来实现对象的深拷贝 Cat cat = new Cat("喵喵", 1); Cat cat2 = cat.clone(); System.out.println("cat : " + cat + ", name : " + cat.name + ", age : " + cat.age); System.out.println("cat2 : " + cat2 + ", name : " + cat2.name + ", age : " + cat2.age); ///至此数组的性质分析完毕 //下面说一下序列化的一些知识 } // 普通类 static class Person { String name; Integer age; public Person(String name, Integer age) { super(); this.name = name; this.age = age; } } // 测试深克隆实体类 static class Man implements Cloneable { String name; Integer age; public Man(String name, Integer age) { this.name = name; this.age = age; } public Object clone() { Man man = new Man(name, age); return man; } } // 测试序列化实体类 static class Dog implements Serializable { private static final long serialVersionUID = -7836461280716041801L; String name; Integer age; public Dog(String name, Integer age) { this.name = name; this.age = age; } // 深拷贝 public Dog deepCopy() throws IOException, ClassNotFoundException { // 先写进流 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream( outputStream); objectOutputStream.writeObject(this); // 再写出流 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( outputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream( byteArrayInputStream); Dog dog = (Dog) objectInputStream.readObject(); objectInputStream.close(); objectOutputStream.close(); return dog; } } // 使用序列化来实现深拷贝 static class Cat implements Serializable, Cloneable { private static final long serialVersionUID = 3530119431127324235L; String name; Integer age; public Cat(String name, Integer age) { this.name = name; this.age = age; } // 深拷贝 public Cat clone() { Cat cat = null; cat = deepCopy(this); return cat; } } public static final void test(String name, int... params) { System.out.println(name); for (int i : params) { System.out.println(i); } } // 简单类型 public static void asList(int... a) { for (int t : a) { System.out.println(t); } } // 普通对象 public static void asList(String... a) { for (String t : a) { System.out.println(t); } } // Object对象,与泛型一致,是二维数组,原因为a其实是一个数组其实就是一个对象, // 看作为一个对象,然后java可变参数再次封装这个数组,成为二维数组 public static void asList(Object... a) { for (Object t : a) { System.out.println(t.getClass().getName()); } } /* * //泛型 public static <T> void asList(T... ts){ for (T t : ts) { * System.out.println(t); } } */ @SuppressWarnings("unchecked") public static <T extends Serializable & Cloneable> T deepCopy(T t) { T newInstance = null; // 先写进流 try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream( outputStream); objectOutputStream.writeObject(t); // 再写出流 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( outputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream( byteArrayInputStream); newInstance = (T) objectInputStream.readObject(); objectInputStream.close(); objectOutputStream.close(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return newInstance; }}
案例输出结果如下:
123-----------------------ABC-----------------------zhangsan123-----------------------[C类名:char[]父类:java.lang.Object实现的接口:java.lang.Cloneablejava.io.Serializablebefore:3before : 1dog : com.zd.test.java.ds.ArrayTest$Dog@4ef53d61, name : 旺旺, age : 2dog2 : com.zd.test.java.ds.ArrayTest$Dog@3fd23632, name : 旺旺, age : 2cat : com.zd.test.java.ds.ArrayTest$Cat@770fba26, name : 喵喵, age : 1cat2 : com.zd.test.java.ds.ArrayTest$Cat@2886f716, name : 喵喵, age : 1
总结如下:
1.泛型和可变参数相遇,我们传过去的数组被包装成了二维数组,因为泛型在java以前的版本中是用Object来代替的,而恰巧的是数组在java中也是一个对象,它是java.lang.Object的子类,可以尝试重载一下,上面的例子我们已经有示范。
2.数组实现了Cloneable和Serializable接口,即数组是可复制和可序列化的。
3.数组的拷贝是浅拷贝,即只拷贝数组中元素的地址,即只拷贝对象的引用。
4.结合Cloneable和Serializable两个接口,可以优雅的实现对象的拷贝和序列化,关于二者的结合使用,上面的范例中已经有解释。之后,我会针对序列化和拷贝再做深入的说明。
个人见解,欢迎指教批评。
1 0
- java数组的对象化,序列化以及拷贝
- java对象的序列化和拷贝
- 03 JAVA 数组补充 拷贝、序列化
- java提高篇-----使用序列化实现对象的拷贝
- java 序列化实现对象的深拷贝
- 使用序列化实现对象的拷贝
- 使用序列化实现对象的拷贝
- 序列化实现对象的拷贝
- 序列化实现对象的拷贝
- 使用序列化实现对象的拷贝
- 使用序列化实现对象的拷贝
- java提高篇-----使用序列化实现对象的拷贝 (深拷贝)
- C#对象的浅拷贝、序列化深拷贝
- Java的对象序列化以及文件IO处理
- Java的对象序列化以及文件IO处理
- 利用序列化将java对象深拷贝
- Java序列化和克隆--对象深度拷贝
- 【Java进阶五】对象序列化和拷贝
- memcache的原理和命中率的总结
- 递归实战(2)字符串全排列
- VMware 网络连接模式
- Caffe框架源码剖析(3)—数据层DataLayer
- 一段错误代码
- java数组的对象化,序列化以及拷贝
- hdu3062 Party--强连通 & 2-sat & 判断可行性
- NSA(美国国安局)泄漏Exploit分析
- 单片机(六)__IIC总线
- 排序算法之插入排序
- SVN Failed to load JavaHL Library.
- 30day plan
- Java NIO Socket VS 标准IO Socket
- 回声抑制器:AEC回声抑制算法