Class加载机制——反射机制

本文深入探讨Java反射机制的概念、原理及应用实例,通过分析Class文件在JVM中的内存分布,阐述反射如何让Class动态加载、实例化、调用方法。结合具体代码示例,展示了反射在学生类中获取属性、构造方法和方法的使用,揭示了反射的强大功能及其在游戏、框架等领域的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[align=center][size=xx-large][b]Class加载机制——反射机制[/b][/size][/align]

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

以下是JVM加载Class的内存分布图:[/size]
[align=center]
[img]http://dl2.iteye.com/upload/attachment/0084/8480/8c54c247-48b0-3c0a-889b-a408dd5a2098.jpg[/img]
[/align]

[size=medium]看到这个图是不是能够联想到Java对象引用的内存分布图呢?[/size]
[align=center]
[img]http://dl2.iteye.com/upload/attachment/0084/8485/0211af6d-8660-39a9-8d3d-cd0f77e59561.jpg[/img]
[/align]

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

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


[size=medium]以下是反射的实例:[/size]

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() + "() {}");
// 拿到方法后可以再拿里面的过程吗?
}

}

}


[size=medium]运行结果:[/size]
[quote]
通过反射拿到对象中的值为:正在吃饭!


//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() {}

}

[/quote]

[size=large][b]疑问:拿到方法后可以再拿里面的过程吗?


欢迎大家批指正!
[/b][/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值