一,类的加载,连接,初始化

java 反射动态注入 java 反射 类加载_java

 

一个类被加载到JVM需要三个步骤:加载,链接,初始化

 

 

1,先说下加载过程

java 反射动态注入 java 反射 类加载_System_02

java 反射动态注入 java 反射 类加载_加载_03

 

 

2,连接

java 反射动态注入 java 反射 类加载_java_04

 注意连接过程分为三个阶段,验证,准备,解析

 

3,初始化

 

java 反射动态注入 java 反射 类加载_java 反射动态注入_05

java 反射动态注入 java 反射 类加载_System_06

 

这里注意:类的加载过程,先加载静态代码块,其次是代码块,然后是构造函数

静态成员之间级别一样,因此谁在前,谁最先被加载

 

二,反射机制

1,先理解下反射

java 反射动态注入 java 反射 类加载_System_07

2,为什么要使用反射

 

java 反射动态注入 java 反射 类加载_java_08

 

可能以上叙述依然很抽象,下面我们用具题代码说明

在开始代码之前我们要先,明白一个对象 java.lang.Class

 

java 反射动态注入 java 反射 类加载_System_09

 

我们可以这样想,java程序在运行前,会把一些类,接口,以及各种资源加载到JVM(java虚拟机)中,如果一个程序有N个类,N个接口,那么JVM在运行程序是就要,一个一个的去找到这些类,接口,如果虚拟机真的运用这种机制,没使用一个类,或者接口都要去遍历所有的接口和类,那么虚拟机要做的工作就太多的,当然java的设计人员也不会允许这样的事情发生。其实在程序加载时,虚拟机会记录每一个加载的类以及接口的具体信息,包括他们的地址,而这些信息就放在了一个叫做Class的对象中,因在虚拟机用到具体的类和接口等资源时,只要通过Class就能够快速访问到(我们可以把Class想象成一张记录了所有资源的文档)

 

代码部分

1,//基类

package com.day17.work;
public class People {
 //属性
	private String pName;
	private String pIdentifyId;
	private String pGender;
	//默认构造函数

	//方法
	public void eat()
	{}

	public void sleep()
	{}

	//get/set方法
	public String getpName() {
		return pName;
	}
	public void setpName(String pName) {
		this.pName = pName;
	}
	public String getpIdentifyId() {
		return pIdentifyId;
	}
	public void setpIdentifyId(String pIdentifyId) {
		this.pIdentifyId = pIdentifyId;
	}
	public String getpGender() {
		return pGender;
	}
	public void setpGender(String pGender) {
		this.pGender = pGender;
	}

}

 

 

2,

//子类,继承了People,以上这两个类是为最后测试准备

package com.day17.work;
public class Student extends People implements Runnable{
 

	private String sSno;
	private String sClass;
	private String sScore;


	public Student()
	{

	}
	public Student(String sSno) {
		super();
		this.sSno = sSno;
	}

	public Student(String sSno, String sClass, String sScore) {
		super();
		this.sSno = sSno;
		this.sClass = sClass;
		this.sScore = sScore;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		//这里实现了Runnable,具体方法不作处理
	}
	public String getsSno() {
		return sSno;
	}
	public void setsSno(String sSno) {
		this.sSno = sSno;
	}
	public String getsClass() {
		return sClass;
	}
	public void setsClass(String sClass) {
		this.sClass = sClass;
	}
	public String getsScore() {
		return sScore;
	}
	public void setsScore(String sScore) {
		this.sScore = sScore;
	}	
	public void student(String couse)
	{}

	public void playGame(String gameName)
	{
		System.out.println(this.getpName()+" Palying "+gameName);
	}

	public void watchTv()
	{}

	public void clickCode(String courseName,int lines)
	{
		System.out.println(this.getpName()+" Click " +courseName+" code "+lines+" lines");
	}
}

 

 

3,

package com.day17.work;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;public class ReflectionDome {
/*本程序输出时并未对输出结果做具体的排版,但应该涉及的方法都有涉及,每一块的
 * 具体功能,代码中都有注释
 * */
	public static void main(String[] args) {
		// TODO Auto-generated method stub		
		//下面方法,根据ppt一个一个来
		//初始化得到对应的Class
		Class<?> studentClass=Student.class;

		//1,构造器
		//返回此Class对象对应类的指定public构造器
		System.out.println("1,关于Class的构造器");
		try {
			Constructor<?> con=studentClass.getConstructor(String.class);
			System.out.println("返回此Class对象对应类的指定public构造器");
			System.out.println(Modifier.toString(con.getModifiers())+" "+con.getName());
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



		//返回此类对象对应类的所有构造器,与权限无关
		Constructor<?>[] cons=studentClass.getDeclaredConstructors();
		System.out.println();
		System.out.println("返回此类对象对应类的所有构造器,与权限无关");
		for(Constructor<?> con:cons)
		{
			System.out.println(con.getName());
			Class<?>[] params=con.getParameterTypes();
			System.out.println("构造函数参数类型");
			for(Class<?> type:params)
			{
				//这里说有参数和类名不做任何排版上的处理,仅仅输出
				System.out.println(type.getTypeName());
			}

		}



		//2,获取Class对象对应类所包含的方法
		//返回所有public方法

		Method[] methods=studentClass.getMethods();
		//循环输出
		System.out.println();
		System.out.println("2,获取Class对象对应类所包含的方法");
		for(Method method:methods)
		{
			System.out.println("所有函数的方法名");
			System.out.println(method.getName());
		}


		//返回指定的public方法
		try {
			System.out.println();
			System.out.println("返回指定的public方法");
			Method method=studentClass.getMethod("playGame", String.class);
			System.out.println(Modifier.toString(method.getModifiers()));
			System.out.println(method.getGenericReturnType());
			System.out.println(method.getName());
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}




		//3,获取Class对应类所包含的Field,返回所有Field,与权限无关
		System.out.println();//为了看着分明一点
		System.out.println("3,获取Class对应类所包含的Field");
		Field[] fields=studentClass.getDeclaredFields();
		//又是遍历
		for(Field field:fields)
		{
			try {
				System.out.println(Modifier.toString(field.getModifiers())+"  "+field.getGenericType()+"  "+field.getName());
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}



			//4,获取Class对象对应类的相关类、接口等
			System.out.println();//为了看着分明一点
			System.out.println("4,获取Class对象对应类的相关类、接口等");
			System.out.println("返回实现的全部接口");
			System.out.println(studentClass.getInterfaces()[0].getName());
			//因为实现了一个借口,所以偷个懒,不再遍历


			System.out.println("返回该Class对象对应类的超类的Class对象");
			System.out.println(studentClass.getSuperclass().getName());		}
		

		//5,获取Class对象对应类的修饰符、所在包、类名等基本信息		System.out.println();
		System.out.println("5,获取Class对象对应类的修饰符、所在包、类名等基本信息");

		//返回此类或接口的所有修饰符。
		//如public、protected、private、final、static、abstract等对应的常量组成,
		//返回的整数应当使用Modifier工具类的方法来解码,才可获取真实的修饰符

		System.out.println(Modifier.toString(studentClass.getModifiers()));

		//获取此类的包
		System.out.println("获取包名     "+studentClass.getPackage());

		//返回此Class对象所表示的类的名称
		System.out.println("Class对象所表示的类的名称    "+studentClass.getName());

		//6,判断该类是否为接口、枚举类型等
		System.out.println();
		System.out.println("6,判断该类是否为接口、枚举类型等");
		Class<?> run=Runnable.class;//这里使用JDK提供的接口进行测试
		System.out.println("是否表示一个接口    "+run.isInterface());


		//7.使用Class对象的newInstance()方法来创建该Class对象对应类的实例,
		System.out.println();
		System.out.println("使用Class对象的newInstance()方法来创建该Class对象对应类的实例,");
		//这里创建一个Student对象,并测试他的一对get/set方法,然后调用调用一个方法作为事例,其他不列举

		try {
			//有一点需要注意,调用此方法newInstance()创建实例,Student必须用于一个无参的构造函数。
			Student stu=(Student) studentClass.newInstance();//这里得到了一个Student
			//实例,与new方法得到的实例等效,下面操作,不再过多赘述
			stu.setpName("张三");
			System.out.println(stu.getpName());

			stu.playGame("LOL");
			stu.clickCode("java",10000);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

 

好了,就先到这了(如果发现代码中有问题,或者是哪里理解有问题,还望不吝赐教!!!)