JAVA反射机制的简单了解

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()。
        第一次写博客,欢迎拍砖!

你可能感兴趣的:(JAVA反射机制的简单了解)