一,类的加载,连接,初始化
一个类被加载到JVM需要三个步骤:加载,链接,初始化
1,先说下加载过程
2,连接
注意连接过程分为三个阶段,验证,准备,解析
3,初始化
这里注意:类的加载过程,先加载静态代码块,其次是代码块,然后是构造函数
静态成员之间级别一样,因此谁在前,谁最先被加载
二,反射机制
1,先理解下反射
2,为什么要使用反射
可能以上叙述依然很抽象,下面我们用具题代码说明
在开始代码之前我们要先,明白一个对象 java.lang.Class
我们可以这样想,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();
}
}
}
好了,就先到这了(如果发现代码中有问题,或者是哪里理解有问题,还望不吝赐教!!!)