一、java的反射机制浅谈

最近研究java研究得很给力,主要以看博文为学习方式。以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出。受到各位指教之处,如若让小生好好感动,说不定会请各位吃饭哦!

1.何谓反射机制

根据网文,java中的反射机制可以如此定义:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2.反射机制如何实现

谈到反射机制,最诱人的莫过于“动态”二字了。接触过C语言的童鞋们都知道,C语言中也有个和“动态”搭上边的函数:malloc()函数。其实这里的两个动态是一个意思,都指的是非编译时处理,抑或运行时处理。这种机制,可以让程序的弹性增加不少,因为借由此机制,客户可以在程序运行时改变一些他关心的性质:分配内存(当然他可能 完全不知道这么做了),调用某个类(当然他还是被蒙在鼓里)等。

下面我们就聊聊java中动态机制是如何实现的。

上一篇文章中提到了java的类的加载问题,但没有更深入地解释其运行机制,在这里就先谈谈这个问题。

首先不得不提到的是java.lang.Class这个类。

有这么一段话:

Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。

也就是说,ClassLoader找到了需要调用的类时(java为了调控内存的调用消耗,类的加载都在需要时再进行,很抠但是很有效),就会加载它,然后根据.class文件内记载的类信息来产生一个与该类相联系的独一无二的Class对象。该Class对象记载了该类的字段,方法等等信息。以后jvm要产生该类的实例,就是根据内存中存在的该Class类所记载的信息(Class对象应该和我所了解的其他类一样会在堆内存内产生、消亡)来进行。

而java中的Class类对象是可以人工自然性的(也就是说开放的)得到的(虽然你无法像其他类一样运用构造器来得到它的实例,因为

Class对象都是jvm产生的。不过话说回来,客户产生的话也是无意义的),而且,更伟大的是,基于这个基础,java实现了反射机制。

获取Class对象有三种方式:

1.通过Object类的getClass()方法。例如:

Class c1 = new String("").getClass();

2.通过Class类的静态方法——forName()来实现:

Class c2 = Class.forName("MyObject");

3.如果T是一个已定义的类型的话,在java中,它的.class文件名:T.class就代表了与其匹配的Class对象,例如:

Class c3 = Manager.class;

Class c4 = int.class;

Class c5 = Double[].class;

这里需要解释一下3:请记住一句话,java中,一切皆对象。也就是说,基本类型int float 等也会在jvm的内存池像其他类型一样中生成

一个Class对象。而数组等组合型数据类型也是会生成一个Class对象的,而且更令人惊讶的是,java中数组的本来面目其实就是某个类,惊讶

中的惊讶是,含有相同元素的相同维数的数组还会共同享用同一个Class对象!其实根据我的臆想,数组的length性质应该就保存在这个Class

对象里面。

Class类中存在以下几个重要的方法:

1.getName()

一个Class对象描述了一个特定类的特定属性,而这个方法就是返回String形式的该类的简要描述。由于历史原因,对数组的Class对象

调用该方法会产生奇怪的结果。

2.newInstance()

该方法可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的默认构造方法。例如:

MyObject x = new MyObject();

MyObject y = x.getClass().newInstance();

3.getClassLoader()

返回该Class对象对应的类的类加载器。

4.getComponentType()

该方法针对数组对象的Class对象,可以得到该数组的组成元素所对应对象的Class对象。例如:

int[] ints = new int[]{1,2,3};

Class class1 = ints.getClass();

Class class2 = class1.getComponentType();

而这里得到的class2对象所对应的就应该是int这个基本类型的Class对象。

5.getSuperClass()

返回某子类所对应的直接父类所对应的Class对象。

6.isArray()

判定此Class对象所对应的是否是一个数组对象。

好啦,现在对Class这个类应该有了一个大致的了解,下面就给出一个反射机制的典型例子供各位分析:

  1. import java.lang.reflect.Array;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.Method;
  5. /**
  6. * Java Reflection Cookbook
  7. *
  8. * @author Michael Lee
  9. * @since 2006-8-23
  10. * @version 0.1a
  11. */
  12. public class Reflection {
  13. /**
  14. * 得到某个对象的公共属性
  15. *
  16. * @param owner, fieldName
  17. * @return 该属性对象
  18. * @throws Exception
  19. *
  20. */
  21. public Object getProperty(Object owner, String fieldName) throws Exception {
  22. Class ownerClass = owner.getClass();
  23. Field field = ownerClass.getField(fieldName);
  24. Object property = field.get(owner);
  25. return property;
  26. }
  27. /**
  28. * 得到某类的静态公共属性
  29. *
  30. * @param className   类名
  31. * @param fieldName   属性名
  32. * @return 该属性对象
  33. * @throws Exception
  34. */
  35. public Object getStaticProperty(String className, String fieldName)
  36. throws Exception {
  37. Class ownerClass = Class.forName(className);
  38. Field field = ownerClass.getField(fieldName);
  39. Object property = field.get(ownerClass);
  40. return property;
  41. }
  42. /**
  43. * 执行某对象方法
  44. *
  45. * @param owner
  46. *            对象
  47. * @param methodName
  48. *            方法名
  49. * @param args
  50. *            参数
  51. * @return 方法返回值
  52. * @throws Exception
  53. */
  54. public Object invokeMethod(Object owner, String methodName, Object[] args)
  55. throws Exception {
  56. Class ownerClass = owner.getClass();
  57. Class[] argsClass = new Class[args.length];
  58. for (int i = 0, j = args.length; i < j; i++) {
  59. argsClass[i] = args[i].getClass();
  60. }
  61. Method method = ownerClass.getMethod(methodName, argsClass);
  62. return method.invoke(owner, args);
  63. }
  64. /**
  65. * 执行某类的静态方法
  66. *
  67. * @param className
  68. *            类名
  69. * @param methodName
  70. *            方法名
  71. * @param args
  72. *            参数数组
  73. * @return 执行方法返回的结果
  74. * @throws Exception
  75. */
  76. public Object invokeStaticMethod(String className, String methodName,
  77. Object[] args) throws Exception {
  78. Class ownerClass = Class.forName(className);
  79. Class[] argsClass = new Class[args.length];
  80. for (int i = 0, j = args.length; i < j; i++) {
  81. argsClass[i] = args[i].getClass();
  82. }
  83. Method method = ownerClass.getMethod(methodName, argsClass);
  84. return method.invoke(null, args);
  85. }
  86. /**
  87. * 新建实例
  88. *
  89. * @param className
  90. *            类名
  91. * @param args
  92. *            构造函数的参数
  93. * @return 新建的实例
  94. * @throws Exception
  95. */
  96. public Object newInstance(String className, Object[] args) throws Exception {
  97. Class newoneClass = Class.forName(className);
  98. Class[] argsClass = new Class[args.length];
  99. for (int i = 0, j = args.length; i < j; i++) {
  100. argsClass[i] = args[i].getClass();
  101. }
  102. Constructor cons = newoneClass.getConstructor(argsClass);
  103. return cons.newInstance(args);
  104. }
  105. /**
  106. * 是不是某个类的实例
  107. * @param obj 实例
  108. * @param cls 类
  109. * @return 如果 obj 是此类的实例,则返回 true
  110. */
  111. public boolean isInstance(Object obj, Class cls) {
  112. return cls.isInstance(obj);
  113. }
  114. /**
  115. * 得到数组中的某个元素
  116. * @param array 数组
  117. * @param index 索引
  118. * @return 返回指定数组对象中索引组件的值
  119. */
  120. public Object getByArray(Object array, int index) {
  121. return Array.get(array,index);
  122. }
  123. }

例子的解释就免了,因为读代码加上自己理解是最好的程序员学习方式。另外,此代码来源为互联网。

java的反射机制的更多相关文章

  1. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  2. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  3. java笔记--反射机制之基础总结与详解

    一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...

  4. JAVA的反射机制学习笔记(二)

    上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...

  5. java笔录---反射机制(1)

    引言   为了方便记忆java的反射机制,在这里仔细的总结了一下.主要是怕以后忘记了,这样也方便回忆.因为最近利用空余时间深入的了解spring和Mybatis框架,   像spring中核心模块IO ...

  6. Java高新技术 反射机制

     Java高新技术 反射机制 知识概要:                   (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...

  7. java的反射机制浅谈(转)

    原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  8. 【转】Java利用反射机制访问私有化构造器

    Java利用反射机制访问私有化构造器 博客分类: java   我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...

  9. 【转】java原理—反射机制

    一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言 ...

随机推荐

  1. 从C#到Objective-C,循序渐进学习苹果开发(5)--利用XCode来进行IOS的程序开发

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.前面几篇随笔主要介绍C#和O ...

  2. HTTP必知必会

    HTTP协议作为网络传输的基本协议,有着广泛的应用.HTTP协议的完整内容很多,但是其核心知识却又简单精炼.学习者应该掌握其基本结构,并且能够举一反三.这篇文章所列的,就是在实际开发中必须知道必须掌握 ...

  3. Model元数据提供机制小结

    在最开始先我得说说我看这部分的情况,最开始被各种ModelMetadata和各种ModelMetadataProvider给搞晕了,就几页书花了我好大的精力去看,直到后来看了一幅类图,细细看各个类之间 ...

  4. c#通过oledb获取excel文件表结构信息

    这个问题来自论坛提问,同理可以获得access等数据库的表结构信息. using System; namespace ConsoleApplication11 { class Program { pu ...

  5. 解决之前上架的 App 在 iOS 9 会闪退问题 (更新:已有 Hotfix)

    最新更新:(2015.10.02) 开发环境: Delphi 10 Seattle OS X El Capitan v10.11 需使用下列 HotfixID: 30398, PAServer Hot ...

  6. Netbeans 8.2将支持PHP 7

    首先,将PHP项目的PHP版本设置为PHP 7.0. PHP 7其中一项新特性是返回类型声明,即PHP的函数和方法可以声明指定类型的返回值: PHP 7的另一项精彩的改进就是参数的标量类型声明,Net ...

  7. 2016 大连网赛---Different GCD Subarray Query(GCD离散+树状数组)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5869 Problem Description This is a simple probl ...

  8. No.019:Remove Nth Node From End of List

    问题: Given a linked list, remove the nth node from the end of list and return its head. For example, ...

  9. Linux命令速查手册,超详细Linux命令教程

    一.常用命令速查 ls cd pwd cat more less tail head cp scp mv mkdir rmdir touch rm ps kill top free clear tre ...

  10. linux系统下nodejs安装过程随记

    首先下载适合的版本.这里我使用的是node v.10.36 先介绍编译安装的详细过程. 下载该版本: wget http://nodejs.org/dist/v0.10.36/node-v0.10.3 ...