4月11日的时候,在看ArrayList类的时候,发现了2个方法:private void writeObject和private void readObject.这两个方法是为了实现串行化而写的,在序列化的时候,ObjectOutputStream和ObjectInputStream使用反射来查找有没有声明这两个方法,然后被ObjectOutputStream和ObjectInputStream调用。针对ArrayList写这两个方法在于:一般类实现了Serializable接口,静态和瞬态的属性不能够序列话,有人会想,那为什么ArrayList让数组array属性为瞬态的呢?我们知道,array是一个对象数组,元素存放的都是地址,序列化没有意义;同时,数组是可以扩充的,没使用的或者没有意义的元素不需要序列化。好了,回到刚刚说的,是ObjectOutputStream和ObjectInputStream调用了writeObject和readObject对吧,可是一个private修饰的方法不是只能被本类调用的吗?这个又是为何?如下:
1.创建一个Reflect类(代码如下)
package org.ping.javase;
public class Reflect {
private String privateReflect = "私有属性:反射";
public String publicReflect = "共有属性:反射";
public Reflect() {
System.out.println("反射类实例化...");
}
public String publicMethod() {
System.out.println(publicReflect);
return publicReflect;
}
private String privateMethod() {
System.out.println(privateReflect);
return privateReflect;
}
private String privateMethodWithArgs(String who) {
System.out.println(who + ";" + privateReflect);
return who + ";" + privateReflect;
}
}
2.创建一个访问Reflect对象的应用类ReflectDemo,代码如下:
package org.ping.javase;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) {
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();// 获取系统类加载器
Class reflectClass = loader.loadClass(Reflect.class.getName());
// 获取Reflect构造器
Constructor constructor = reflectClass.getConstructor((Class[])null);
// 获取Reflect实例
Reflect reflect = (Reflect) constructor.newInstance();
//reflect.publicMethod();
Field publicField = reflectClass.getField("publicReflect");
System.out.println(publicField.get(reflect));
Field privateField = reflectClass.getDeclaredField("privateReflect");
// 抑制Java的访问控制检查
privateField.setAccessible(true);
System.out.println(privateField.get(reflect));
System.out.println("-----" + privateField.get(reflectClass.newInstance()));
Method method = reflectClass.getDeclaredMethod("privateMethod");
// 抑制Java的访问控制检查
method.setAccessible(true);
method.invoke(reflectClass.newInstance());
Method method1 = reflectClass.getDeclaredMethod("privateMethodWithArgs", new Class[]{String.class});
// 抑制Java的访问控制检查
method1.setAccessible(true);
method1.invoke(reflectClass.newInstance(), new Object[]{"李连杰"});
} catch(ClassNotFoundException cfe) {
cfe.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
如下运行后,结果:
反射类实例化...
共有属性:反射
私有属性:反射
反射类实例化...
-----私有属性:反射
反射类实例化...
私有属性:反射
反射类实例化...
李连杰;私有属性:反射
总结:private void writeObject(ObjectOutputStream stream)方法里面有这么两行:
stream.defaultWriteObject();
for (int i = 0; i < size; i++) {
stream.writeObject(array[i]);
}
其中defaultWriteObject()是序列化那些非静态和非瞬态(transient)属性
后面的stream.riteObject[arry[i]]就是你自己要序列化的属性了。
读取的时候(readObject),也是一个循环,然后赋值语句:array[i] = stream.readObject()。
第一次写博客,欢迎拍砖!
转载于:https://my.oschina.net/TtSjIQ/blog/221130