java 类的加载及反射机制

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

 

一个类被加载到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();
}

}
}

 

 

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

posted @ 2015-08-11 19:53  就这样e  阅读(207)  评论(0编辑  收藏  举报