Class加载机制——反射机制

Class加载机制——反射机制


        最近学习了动态加载Class.forName,知道了动态加载的应用流程,觉得这是一个很棒的功能,可以让Class动态加载,并且可以newInstance实例,invoke方法;在游戏中角色的加入、SSH框架的内部实现、Eclipse的自动补全功能等等都应用到了动态加载机制;Java动态加载太神奇了。但今天走进JVM内部一看才发现,哇,原来就是这样一回事!

         以下是JVM加载Class的内存分布图:


Class加载机制——反射机制_第1张图片


        看到这个图是不是能够联想到Java对象引用的内存分布图呢?

Class加载机制——反射机制_第2张图片


        这样对比就很容易理解到,JVM将Class文件也作为了一个个的对象存在于内存中,因此当我们通过反射去获取其中的元素时,就和我们平时使用一个普通Java对象一样方便。

重点:Class文件在JVM中是以对象的形式存在!这就是反射的内部原理!



以下是反射的实例:
package com.sean.ioc;

/**
 * 学生类
 * 
 * @author Sean 2013-5-21
 * 
 */
public class Student {

	public String Sno;
	private String Sname;
	private String Ssex;
	private int Sage;
	private String Sclass;
	private String Smajor;

	public String getSno() {
		return Sno;
	}

	public void setSno(String sno) {
		Sno = sno;
	}

	public String getSname() {
		return Sname;
	}

	public void setSname(String sname) {
		Sname = sname;
	}

	public String getSsex() {
		return Ssex;
	}

	public void setSsex(String ssex) {
		Ssex = ssex;
	}

	public int getSage() {
		return Sage;
	}

	public void setSage(int sage) {
		Sage = sage;
	}

	public String getSclass() {
		return Sclass;
	}

	public void setSclass(String sclass) {
		Sclass = sclass;
	}

	public String getSmajor() {
		return Smajor;
	}

	public void setSmajor(String smajor) {
		Smajor = smajor;
	}

	public String doSomething() {
		return "正在吃饭!";

	}

}


package com.sean.ioc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Java 反射机制
 * 
 * @author Sean 2013-5-21
 * 
 */
public class Reflect {

	/**
	 * 测试
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		Object stu = forReflect("com.sean.ioc.Student");

	}

	/**
	 * 反射机制
	 * 
	 * @param string
	 *            对象
	 * @return
	 */
	private static Object forReflect(String className) {
		Class thisClass = null;
		try {
			thisClass = Class.forName(className);
		} catch (Exception e) {
			e.printStackTrace();
		}
		getThisClassProperty(thisClass);
		System.out.println("//Student类");
		getThisClassName(thisClass);
		System.out.println("//类的属性");
		getThisClassFields(thisClass);
		System.out.println("//类的构造方法");
		getThisClassConstrName(thisClass);
		System.out.println("//类的方法");
		getThisClassMethods(thisClass);
		System.out.println();
		System.out.println("}");

		return null;
	}

	/**
	 * 通过类反射出对象中的处理结果
	 */
	private static void getThisClassProperty(Class thisClass) {
		try {
			Object obj = thisClass.newInstance();
			Method method = thisClass.getMethod("doSomething", null);
			String sth = (String) method.invoke(obj, null);
			System.out.println("\n\n通过类反射出对象中的处理结果:" + sth + "\n\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取这个类名
	 * 
	 * @param thisClass
	 */
	private static void getThisClassName(Class thisClass) {
		System.out.println(thisClass.getPackage());
		System.out.println();

		System.out.println("public class " + thisClass.getSimpleName() + "{");

	}

	/**
	 * 获取属性
	 * 
	 * @param thisClass
	 */
	private static void getThisClassFields(Class thisClass) {
		if (thisClass.getDeclaredFields().length > 0) {
			Field[] field = thisClass.getDeclaredFields();
			for (Field i : field) {
				System.out
						.println(i.toString().substring(0,
								i.toString().indexOf(" "))
								+ "  "
								+ i.getType()
										.toString()
										.substring(
												i.getType().toString()
														.lastIndexOf(".") + 1)
								+ "  " + i.getName() + ";");
				// 只能拿到public 访问类型的属性吗?
			}
		}

	}

	/**
	 * 获取这个类的构造方法
	 * 
	 * @param thisClass
	 */
	private static void getThisClassConstrName(Class thisClass) {
		try {
			Constructor[] con = thisClass.getConstructors();
			for (Constructor i : con) {
				System.out.println(i.toString().substring(0,
						i.toString().indexOf(" "))
						+ "  "
						+ i.getName().substring(
								i.getName().lastIndexOf(".") + 1) + "{}");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取类中的方法
	 * 
	 * @param thisClass
	 */
	private static void getThisClassMethods(Class thisClass) {
		Method[] method = thisClass.getDeclaredMethods();

		for (Method i : method) {
			System.out.println(i.toString().substring(0,
					i.toString().indexOf(" "))
					+ "  "
					+ i.getReturnType()
							.toString()
							.substring(
									i.getReturnType().toString()
											.lastIndexOf(".") + 1)
					+ "  "
					+ i.getName() + "()  {}");
			// 拿到方法后可以再拿里面的过程吗?
		}

	}

}


运行结果:
引用

通过反射拿到对象中的值为:正在吃饭!


//Student类
package com.sean.ioc

public class Student{
//类的属性
public  String  Sno;
private  String  Sname;
private  String  Ssex;
private  int  Sage;
private  String  Sclass;
private  String  Smajor;
//类的构造方法
public  Student{}
//类的方法
public  String  doSomething()  {}
public  String  getSno()  {}
public  void  setSno()  {}
public  String  getSname()  {}
public  void  setSname()  {}
public  String  getSsex()  {}
public  void  setSsex()  {}
public  int  getSage()  {}
public  void  setSage()  {}
public  String  getSclass()  {}
public  void  setSclass()  {}
public  String  getSmajor()  {}
public  void  setSmajor()  {}

}



疑问:拿到方法后可以再拿里面的过程吗?


欢迎大家批指正!


你可能感兴趣的:(java,jvm)