首页 / JAVA / Java中类加载机制和反射技术
Java中类加载机制和反射技术
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java中类加载机制和反射技术,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3507字,纯文字阅读大概需要6分钟。
内容图文
我们知道一个对象在运行时有两种类型,一个是编译类型,一个是运行时类型。在程序运行时,往往是需要发现类和对象的真实的信息的。那么如何获的这种信息呢?
其一,如果我们在编译和运行时都知道类型的具体信息,这时是可以手动将一个对象转换为运行时的类型。
其二,如果我们在编译时无法预知对象和类到底是属于哪些类,那么程序只有依靠运行时的信息来发现对象和类的真实的信息了,这时就必须要用到反射技术。
在谈具体的发射技术之前,我想先回顾下,有关类的加载的一些基本的性质和原理,以方便我们更好地理解,反射的作用和特点。而实际上,一个类如果可以被执行,那么对于JVM来说,它的执行流程为:类的加载、连接、初始化。通过这种方式,才可以获取到一个类的类对象,即java.lang.Class对象,并在此基础上获取到该类的成员变量,方法和构造器等内在的东东。
那么,什么是类的加载呢?类的加载就是将类的class文件读入内存,并为之创建一个java.lang.Class对象,也就是说当程序使用任何类时,系统都会为之建立一个java.lang.Class对象。同时,类的加载是由类加载器完成的。
类的连接:连接阶段负责把类的二进制数据合并到JRE中。第一,验证,检验被加载的类是否有正确的内部结构;第二,准备,负责为类的类变量分配内存,并设置默认初始值。第三,解析将类的二进制数据中的符号引用替换成直接引用。类的初始化,主要对类变量进行初始化。
这样,我们清楚地认识到了一个类的生命周期变化,那么这些也为我们的反射机制带来了铺垫,要获取一个类的class对象,有三重方式:
(1)使用Class类的forName(String clazzName)静态方法
(2)调用某个类的class属性获取该类对应的Class对象
(3)调用某个类的getClass()方法
通过这三种手段就可以获取到了一个类的Class对象,这样就可以动态获取该对象的实际的信息了。下面通过一个具体的例子说明下,如果通过反射机制,创建一个类的对象,如何通过获取的对象再进一步获取该对象的属性和方法,以及动态为该对象注入新的参数值。
1 package ReflectionEntity; 2 import java.util.Date; 3 4 /** 5 * @author XuJiaqing 6 * 7 */ 8 public class Student { 9 // get/set方法 10 public String getStudentID() { 11 return studentID; 12 } 13 14 public void setStudentID(String studentID) { 15 this.studentID = studentID; 16 } 1718public String getStudentName() { 19return studentName; 20 } 2122publicvoid setStudentName(String studentName) { 23this.studentName = studentName; 24 } 2526public Date getBirthday() { 27return birthday; 28 } 2930publicvoid setBirthday(Date birthday) { 31this.birthday = birthday; 32 } 3334publicint getScore() { 35return score; 36 } 3738publicvoid setScore(int score) { 39this.score = score; 40 } 4142private String studentID;//学生id43public String studentName;//学生姓名44private Date birthday;//学生生日45privateint score;//学生成绩 46//实现的任务 的方法47publicvoid achieveTask(String taskName) { 48 System.out.println(studentName + "实现了" + taskName + "技术"); 49 } 50 }
package ReflectionTest; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import ReflectionEntity.Student; /** * @author XuJiaqing * */ public class test { public static void main(String[] args) { // TODO Auto-generated method stub try { // 获取Student的Class对象 Class<?> clazz = Class.forName("ReflectionEntity.Student"); // 获取该类中所有的属性 Field[] fields = clazz.getDeclaredFields(); // 遍历所有的属性for (Field field : fields) { // 打印属性信息,包括访问控制修饰符,类型及属性名 System.out.println(field); System.out.println("修饰符:" + Modifier.toString(field.getModifiers())); System.out.println("类型:" + field.getType()); System.out.println("属性名:" + field.getName()); } // 获取该类中的所有方法 Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { // 打印方法签名 System.out.println(method); System.out.println("修饰符:" + Modifier.toString(method.getModifiers())); System.out.println("方法名:" + method.getName()); System.out.println("返回类型:" + method.getReturnType()); // 获取方法的参数对象 Class<?>[] clazzes = method.getParameterTypes(); for (Class<?> class1 : clazzes) { System.out.println("参数类型:" + class1); } } // 通过Class对象创建实例 Student student = (Student) clazz.newInstance(); // 获取属性名为studentName的字段(Field)对象,以便下边重新设置它的值 Field studentName = clazz.getField("studentName"); // 设置studentName的值为”XuJiaqing“ studentName.set(student, "XuJiaqing"); // 通过Class对象获取名为”finishTask“,参数类型为String的方法(Method)对象 Method finishTask = clazz.getMethod("achieveTask", String.class); // 调用achieveTask方法 finishTask.invoke(student, "反射"); } catch (Exception e) { e.printStackTrace(); } } }
包的目录结构和运行结果为:
原文:http://www.cnblogs.com/jiaqingshareing/p/6024541.html
内容总结
以上是互联网集市为您收集整理的Java中类加载机制和反射技术全部内容,希望文章能够帮你解决Java中类加载机制和反射技术所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。