最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象。

什么是反射机制?

“JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。”
我们通过一些例子,更好理解反射机制。
Class类

我们知道Java是一门面向对象语言,在Java的世界里,万物皆为对象,比如我们有一个Person类:

public class Person { }

我们创建一个Person类的实例,Person person = new Person; 那么这个person,就是Person类的实例对象。
那么既然万物都为对象,所以类也是对象。

类是什么的对象呢?类是Class类的对象,表示方式有三种:

//第一种,任何一个类都有一个隐含的静态成员变量class Class c1 = Person.class; //第二种,已经知道该类的对象,通过getClass获得 Class c2 = person.getClass; //第三种,Class类的forName方法 Class c3 = Class.forName("Person"); //这里,c1,c2,c3都是Class类的实例,我们称c1, c2 ,c3为Person类的类类型 //不难看出,c1 == c2结果是true, c2 == c3结果也是true
通过类的类类型,我们经常会用到的方法就是newInstance方法,通过该方法可以创建该类的实例:

Person personA = new Person; //直接new一个实例 Person personB = Person.class.newInstance; //通过newInstance方法获得Person的实例 //在学习JAVAEE时候,newInstance方法我们最常见于获取数据库驱动 Class.forName("com.mysql.jdbc.Driver").newInstance; //需要注意的是,在使用newInstance方法的前提是该类必须要有无参构造方法

动态加载类:

编译时刻加载类称为静态加载,运行时刻加载类称为动态加载,使用new方法新建实例即为静态加载类,在编译时候就要加载全部类。这里我们举一个例子:
为了更好的区分编译和运行,我们不适用IDE工具,而使用记事本来实现这个例子:
//我们举女娲造人的例子,创建一个CreatePerson类 public class CreatePerson { public static void main(String[] args) { if(args[0].equalsIgnoreCase("man")) { //如果从命令行传入的参数为man 则创建Man的实例并调用say方法 new Man.say; } if(args[0].equalsIgnoreCase("woman")) { //如果从命令行传入的参数为woman 则创建Woman的实例并调用say方法 new Woman.say; } } } //CreatePerson类用到了2个类,分别是Man和Woman。 //但是我们现在只创建Man类 public class Man { public void say { System.out.println("I am a man !"); } }
我们在CMD中编译CreatePerson,看看会发生什么:

JAVA反射机制—学习总结
提示我们找不到Woman这个类。这就是静态加载,在编译时刻需要加载全部类。那么问题来了,如果我要写一个程序,里面有100个功能,这100个功能分别由100个类实现,那么一旦缺少一个类,这整个程序是不是就不能用了。

为了解决这个问题,我们可以使用动态加载。我们把上面这个例子改一下:

//创建一个Person接口 public interface Person { void say; } //修改Man类,继承Person接口 public class Man implements Person{ public void say { System.out.println("I am a man !"); } } //修改CreatePerson类,实现动态加载类 public class CreatePerson{ public static void main(String[] args) { try{ //动态加载类 Class c = Class.forName(args[0]); //通过类的类类型,创建该类实例对象 Person person = (Person)c.newInstance; person.say; } catch(Exception e) { e.printStackTrace; } } }

这个时候,我们再进行编译:
没有报错了,那么我们继续把Man编译,再运行一下:
如果我们在命令行中输入的参数是Woman呢?
JAVA反射机制—学习总结
抛出ClassNotFoundException异常。因为我们并没有创建Woman类,所以如果以后需要创建Woman类实例,我们只需要新建一个Woman类,并实现Person接口就行了。
通过反射机制,获得类的信息
在Java反射机制的定义中有:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。下面是一个实例:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ClassUtil { /** * 获取成员函数的信息 */ public static void getClassMethodMessage(Object obj) { Class c = obj.getClass; //获取类的名称 //System.out.println(c.getName); /** * * Method类,方法对象 *getMethods方法获得所有public的方法,包括继承而来 *getDeclaredMethods是获取该类自己的声明的方法 */ Method ms = c.getMethods; for(int i = 0; i < ms.length; i++) { //得到方法的返回值类型的类类型 Class returnType = ms[i].getReturnType; System.out.print(returnType.getName + " "); //得到方法的名称 System.out.print(ms[i].getName + "("); //获取参数类型 Class paramTypes = ms[i].getParameterTypes; for(Class class1:paramTypes) { System.out.print(class1.getName + ","); } System.out.println(")"); } } public static void getFieldMessage(Object obj) { Class c = obj.getClass; /** * 成员变量也是对象 * java.lang.reflect.Field * */ Field fs = c.getDeclaredFields; for(Field field:fs) { //得到成员变量类型的类类型 Class fieldType = field.getType; String typeName = fieldType.getName; //得到成员变量的名称 String fieldName = field.getName; System.out.println(typeName + " " + fieldName); } } public static void printConMessage(Object obj) { Class c = obj.getClass; /** * 构造函数也是对象 * */ Constructor cs = c.getConstructors; for (Constructor constructor : cs) { System.out.print(constructor.getName + "("); //获取构造函数参数列表------>参数列表的参数类型 Class paramType = constructor.getParameterTypes; for (Class class1 : paramType) { System.out.print(class1.getName + ","); } System.out.println(")"); } } public static void main(String[] args) { String s = "hello"; getFieldMessage(s); ClassUtil.printConMessage(s); getClassMethodMessage(s); } }

方法的反射操作

可以通过方法的反射操作实现方法的调用:
import java.lang.reflect.Method; public class MethodDemo1 { public static void main(String[] args) { //要获取print(int, int) //要获取类的方法就要获取类的信息,获取类的信息就要获取类的类类型 A a1 = new A; Class c = a1.getClass; //2,获取方法 名称和参数列表 //getMethod获取的是public的方法 try { Method m = c.getDeclaredMethod("print", int.class,int.class); //方法的反射操作 //a1.print(10, 20);方法的反射操作,用m来进行方法调用和前者效果一致 Object obj = m.invoke(a1, 10,20);//如果方法有返回值返回值,没有就null } catch (Exception e) { e.printStackTrace; } } } class A { public void print(int a , int b) { System.out.println(a + b); } public void print(String a , String b) { System.out.println(a.toUpperCase + "," + b.toUpperCase); } }

以上是我今天对Java反射机制的学习总结,如果大家有更好的理解,欢迎在留言区评论交流,互相学习。

稿源:微信小程序开发www1.qixoo.com

JAVA反射机制—学习总结的更多相关文章

  1. Java反射机制——学习总结

    前几天上REST课,因为涉及到Java的反射机制,之前看过一直没有用过,有些遗忘了,周末找了些资料来重新学习,现在总结一下,加深印象. 什么是反射机制? 参考百度百科对java反射机制的定义: “JA ...

  2. Java反射机制学习与研究

    Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...

  3. Java反射机制学习

    Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答 ...

  4. JAVA反射机制学习随笔

    JAVA反射机制是用于在运行时动态的获取类的信息或者方法,属性,也可以用来动态的生成类,由于所有类都是CLASS的子类,我们可以用一个CLASS类的实例来实例化各种类 例如: Class<?&g ...

  5. java反射机制学习小结

    之前一直对java的反射机制理解得很模糊,今天因为学习spring,所以花了些时间总算把它理顺了,记录一下 另外,推荐读读这篇文章,写的挺好的http://blog.csdn.net/woshixuy ...

  6. java反射机制学习笔记

    内容引用自:https://www.cnblogs.com/wkrbky/p/6201098.html https://www.cnblogs.com/xumBlog/p/8882489.html,本 ...

  7. Java 反射机制学习资料

    Java反射——引言 Java反射——Class对象 Java反射——构造函数 Java反射——字段 Java反射——方法 Java反射——Getter和Setter Java反射——私有字段和私有方 ...

  8. java反射机制学习代码

    根据 http://www.iteye.com/topic/137944 文档进行学习 代码如下: package reflectTest; import java.lang.reflect.*; i ...

  9. Java反射机制的学习

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

随机推荐

  1. http协议详解<一>

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://7826443.blog.51cto.com/7816443/1729227 写在 ...

  2. NOI 1.7编程基础之字符串(35题)

    01:统计数字字符个数 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一行字符,统计出其中数字字符的个数. 输入 一行字符串,总长度不超过255. 输出 ...

  3. VelocityTracker

    VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch event, VelocityTracker通过跟踪一连串事件实时计算出 当前的速度,这样的用法在androi ...

  4. Linux共享库 日志方法

    mylog.h #ifdef __cplusplus extern "C" { #endif //写日志函数 //path:日志文件名 //msg:日志信息 int writelo ...

  5. c语言 指针的值

    int num = 1; int *p = &num; printf("%x", &num);//打印 0x7dfe88 printf("\n%x&quo ...

  6. [CareerCup] 9.1 Climbing Staircase 爬楼梯

    9.1 A child is running up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps a ...

  7. RocEDU.阅读.写作《你的灯亮着吗?》

    <你的灯亮着吗?> 一.对本书的认识 这本书的作者就如何训练思维能力指点迷津.书中提及的观点包括"问题是理想状态和现实状态之间的差别",以及"无论表面上表现的 ...

  8. VC++中复制对话框资源 之较好方法之一

    资源对话框的编写有时候较为麻烦,这里我成功实现了这个方法的可用性,具体如下: 碰到模块移植问题了,自己做的对话框类(继承于CDialog)要移植到目标工程中.在网上搜了几个帖子发现都说的很生涩.   ...

  9. 工作随笔——tar命令批量解压

    由于linux的tar命令不支持批量解压,所以很多网友编写了好多支持批量解压的shell命令,收集了一下,供大家分享: 第一: for tar in *.tar.gz; do tar xvf $tar ...

  10. 运用Java对微信公众平台二次开发技术——开发者模式接入

    当初我在这碰到了很多问题,市面上以及网络上的资料特别少,所以当初碰了很多壁,所以现在跟大家分享一下,如何用Java,对微信公众平台进行二次开发. 一.开发预备知识: 最基本的JavaSE与JavaWe ...