java类级别反射_java 类的加载及反射机制

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

d9d2417da5f37189b26dd1b7c7de9195.png

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

1,先说下加载过程

820b29768a2b7635438fe27bedc25b32.png

829e6a487c6a063f3af6841dcab2fa68.png

2,连接

bb548ad1087827ddb4f4c12b29b79e22.png

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

3,初始化

dc29da7eab5b2b4dc18c236405338b44.png

a3c1de93220bddf6dd6fd05ef9c86b3c.png

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

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

二,反射机制

1,先理解下反射

69498a5399fc8b232a866eb52e9ccb31.png

2,为什么要使用反射

7a57ae9f54a59302348a981f9d127ec4.png

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

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

4eb7fd90d36f1ad3d508bb3e23d16bd0.png

我们可以这样想,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();

}

}

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值