学习目标:

1.什么是反射:即反射的定义,

2.反射有什么作用,能解决什么问题,

3.反射的知识点是什么,

4.反射的利弊

5.反射的例子

1.什么是反射:反射的定义:

a) 能够分析类能力的程序被称为反射(reflective)

2.反射的作用,能解决什么问题:

1.在运行中分析类的能力

2.在运行中查看对象

3.实现数组的操作代码

4.利用Method对象,这个对象很像c++中的函数指针

使用反射的主要人员是工具构造者,而不是应用程序员。

反射机制最重要的内容:检查类的结构。

3.反射的知识点:

a) Class类:

所有对象都有一个运行时的类型标识,它保存着每个对象所属的类足迹,保存这些信息的类被称为Class。Object类中的getClass()方法会返回一个Class类型实例。

获取Class类对象的三种方法:

1. Class c = objectName.getClass();

如Employee e;

Class c = e.getClass();

2. 调用静态方法forName获得类名对应的Class对象

如String className = "java.util.Date";

Class c = Class.forName(className);

3. java类型.class

如Class c = Date.class;

Class c1 = int.class;

Class c2 = Double[].class;

Class类的方法:

最常用的Class方法是getName()方法,将返回类的名字;getFields、getMethods、getConstructors方法将返回类提供的public域、方法、构造器数组,其中包括超类的共有成员;getDeclareFields、getDeclareMethods、getDeclareConstructors方法将分别返回类中声明的全部域、方法、构造器,包括私有和受保护成员,但不包括超类的成员。

b) 在java.lang.reflect包中有一些类Field、Method、Constructor、Modifier、Array

i. Field用于描述类的域:getType方法,返回域所属类型的Class对象;

ii. Method用于描述类的方法:有报告返回类型的方法;

iii. Constructor用于描述类的构造器

类的共性:三个类都有getName方法,返回项目名称;三个类都有getModifiers的方法,它将返回一个整数值,用不同的位开关描述public和static这样的修饰符使用状况;Method类和Constructor类有报告参数类型的方法;

iv. Modifier类:可用其中的静态方法分析getModifiers返回的整数值,如使用其中的isPublic、isPrivate或isFinal判断方法或构造器是否是public、private或final。toString方法将修饰词法打印出来。

v. Array类:允许动态的创建数组。其中的静态方法newInstance,它能构建新数组,必须提供两个参数:数组的元素类型、数组的长度。静态方法getLength能获得数组的长度。获得新数组元素类型有三步:1.首先获得a数组的类对象,2.确认它是一个数组,3.使用Class类的getComponentType方法确定数组对应的类型。

c) 在运行时查看数据域的实际内容

利用反射机制可以查看在编译期间还不清楚的对象域。查看对象域的关键方法是Field类中的get方法,例如f是一个field类型的对象,obj是某个包含f域的类的对象,f.get(obj)将返回一个对象,其值为obj对象f域的当前值。

Employee harry = new Employee("Harry Hacker", 3500, 10, 1, 1989);

Class c = harry.getClass();

Field f = c.getDeclaredField("name");

f.setAccessible(true);

Object v = f.get(harry);

注意:因为name是一个私有域,直接用get方法会抛出异常,只有先用setAccessible方法,使其先不受安全管理器的控制,才可以访问。setAccessible方法是AccessibleObject类中的一个静态方法,它是Field、Method、Constructor类的公共超类。

当然,可以获得就可以设置,调用f.set(obj, value);可以将obj对象的f域设为新值。

d)  使用反射编写泛型数组代码

能编写一个用于扩展数组的通用方法。

用到java.lang.reflect包中的Array类,如下:

static Object arrayGrow(Object a) //是Object,不是Object[]。

{

Class c1 = a.getClass();

if(!c1.isArray()) return null;

Class componentType = c1.getComponentType();

int length = Array.getLength(a);

int newLength = length*11/10+10;

Object newArray = Array.newInstance(componentType,newLength);

System.arraycopy(a,0,newArray,0,length);

return newArray;

}

注:int[] 可以被转换成Object,但不能转换成对象数组。可以将一个对象数组临时转换成Object[]数组,然后再把它转换回来是可以的,但一个从一开始就是Object[]的数组却不能转换成非Object对象数组;

e)  方法指针:

方法指针是指将一个方法的存储地址传给另外一个方法,以便第二个方法能够随后调用它。从表面上看,java没有提供方法指针,事实上,java设计者说过方法指针很危险,但是在java1.1中,方法指针以作为反射包的副产品出现了。

在Method类中有一个invoke方法,它允许调用包装在当前Method对象中的方法。

4.反射的利弊:

a) 反射机制可以使人们可以在运行时查看方法和域,让人编写出更具通用性的程序。这种功能对编写系统程序来说极为有用,但通常不适用于编写应用程序。

b) 反射很脆弱,编译器很难帮助人发现程序中的错误,任何错误只能在运行时发现,并导致异常。

5.反射的例子:

利用反射打印一个类的构造函数、方法、域

点击(此处)折叠或打开

  1. public class ReflectTest {
  2. public static void main(String[] args){
  3. String name;
  4. if(args.length > 0){
  5. name = args[0];
  6. }else{
  7. Scanner in = new Scanner(System.in);
  8. System.out.println("Enter class name (e.g. java.util.Date): ");
  9. name = in.next();
  10. }
  11. try{
  12. //print class name and superclass name(if != Object)
  13. Class c1 = Class.forName(name);
  14. Class superc1 = c1.getSuperclass();
  15. String modifiers = Modifier.toString(c1.getModifiers());
  16. if(modifiers.length() > 0)    System.out.print(modifiers+" ");
  17. System.out.print("class "+name);
  18. if(superc1 != null && superc1 != Object.class)    System.out.println(
  19. " extends"+superc1.getName());
  20. System.out.print("\n{\n");
  21. printConstructors(c1);
  22. printMethods(c1);
  23. printFields(c1);
  24. System.out.println("}");
  25. }catch(ClassNotFoundException e){
  26. e.printStackTrace();
  27. }
  28. System.exit(0);
  29. }
  30. /*
  31. * prints all constructors of a class
  32. */
  33. public static void printConstructors(Class c1){
  34. Constructor[] constructors = c1.getConstructors();
  35. for(Constructor c:constructors){
  36. String name = c.getName();
  37. System.out.print(" ");
  38. String modifiers = Modifier.toString(c1.getModifiers());
  39. if(modifiers.length() > 0) System.out.print(modifiers+" ");
  40. System.out.print(name+"( ");
  41. //print parameter types
  42. Class[] paramTypes = c.getParameterTypes();
  43. for(int j=0; j<paramTypes.length; j++){
  44. if(j>0) System.out.print(", ");
  45. System.out.print(paramTypes[j].getName());
  46. }
  47. System.out.println("); ");
  48. }
  49. }
  50. /**
  51. * prints all methods of a class
  52. */
  53. public static void printMethods(Class c1){
  54. Method[] methods = c1.getMethods();
  55. for(Method m : methods){
  56. Class retType = m.getReturnType();
  57. String name = c1.getName();
  58. System.out.print(" ");
  59. //print modifiers,return type and method name
  60. String modifiers = Modifier.toString(m.getModifiers());
  61. if(modifiers.length() > 0) System.out.print(modifiers + " ");
  62. System.out.print(retType.getName() + " "+name+"(");
  63. //print parameter types
  64. Class[] paramTypes = m.getParameterTypes();
  65. for(int j = 0; j<paramTypes.length; j++){
  66. if(j>0) System.out.print(", ");
  67. System.out.print(paramTypes[j].getName());
  68. }
  69. System.out.println(");");
  70. }
  71. }
  72. /**
  73. * print all fields of a class
  74. */
  75. public static void printFields(Class c1){
  76. Field[] fields = c1.getDeclaredFields();
  77. for(Field f : fields){
  78. Class type = f.getType();
  79. String name = f.getName();
  80. System.out.print(" ");
  81. String modifiers = Modifier.toString(f.getModifiers());
  82. if(modifiers.length() > 0) System.out.print(modifiers+" ");
  83. System.out.println(type+" "+name+";");
  84. }
  85. }
  86. }

java开发--反射技术的更多相关文章

  1. Java的反射技术

    什么是反射机制 Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能调用它的任意属性和方法.这种动态获取信息以及动态调用对象属性和方法的即使称为J ...

  2. Java采用反射技术创建对象后对目标类的成员变量和成员方法进行访问

    实现: package com.ljy; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * * @Class ...

  3. Java通过反射技术动态创建对象(有参、无参构造)

    实现类: package com.ljy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTarge ...

  4. 2015网易校招Java开发工程师(技术架构)在线笔试题

    1.  程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process ...

  5. java开发常用技术

    基础部分 1. 线程和进程的区别 线程三个基本状态:就绪.执行.阻塞 线程五个基本操作:创建.就绪.运行.阻塞.终止 进程四种形式:主从式.会话式.消息或邮箱机制.共享存储区方式 进程是具有一定功能的 ...

  6. 2015年网易校招Java开发工程师(技术架构)在线笔试题

    1.  程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process ...

  7. java 使用反射技术解耦

    1.调用的代码 /src/de/test.java package de; public class Test { public static void main(String[] args) { D ...

  8. java开发目前技术选型

    目前系统采用 1.后端 服务框架:Dubbo.zookeeper 缓存:Redis.ehcache 消息中间件:ActiveMQ,kafka 负载均衡:Nginx 分布式文件:FastDFS 数据库连 ...

  9. Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框

    原文出处:博主宇宙的极客http://www.cnblogs.com/nokiaguy/archive/2010/07/27/1786482.html 众所周知,AlertDialog类用于显示对话框 ...

随机推荐

  1. 动态链接库知识点总结之三(如何以显示的方式加载DLL)

    总结一下如何显示加载方式加载DLL, 首先,我们新建一个win32项目,选择dll,空项目,再添加一个源文件,一个模块定义文件(.def),具体如下图.(详细方法已经在前两篇文章中讲述,如有不懂,打开 ...

  2. MATLAB连通域标记函数

    L = bwlabel(BW,n)返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1.2.num(连通区域的个数).n的值为4或8,表示是按4连通寻找区域,还是 ...

  3. [转载]poi导出excel,可以自定义保存路径

    poi导出excel比js导出excel安全性更好,在使用poi导出excel时,先要导入poi-3.5-FINAL-20090928.jar包到你项目的lib目录下,我这里选择是3.5版的 1.ac ...

  4. 清除IE中Ajax缓存,Chrome不需要

    做项目的时候,会遇到这种情况,通过ajax从后台获取的数据在chrome上显示的是最新的,而在IE上却是以前的数据,这是为什么呢,在我百般调试下终于发现原来是因为IE的ajax缓存的原因,于是加上这段 ...

  5. mobiscroll 控件的使用(手机端日历控件)

    先上一张图吧: 控件的下载地址:http://www.kuitao8.com/20140604/2615.shtml 文档API地址:http://docs.mobiscroll.com/2-13-2 ...

  6. MySQL高可用读写分离方案预研

    目前公司有需求做MySQL高可用读写分离,网上搜集了不少方案,都不尽人意,下面是我结合现有组件拼凑的实现方案,亲测已满足要求,希望各位多提建议 :) 一.    网上方案整理(搜集地址不详...) 1 ...

  7. Portion of class Throwable’s inheritance hierarchy

  8. 三星wep200蓝牙耳机中文说明书

    给耳机充电:耳机内部装有充电电池,第一次使用之前电一定要充满1,先将耳机放入所提供的充电盒中,关上盖.2,将配置器的接头插入充电盒的座孔内.并将另一端插入电源插座.*充电一直充到耳机指示灯由红变蓝*大 ...

  9. 【BZOJ】【1503】 【NOI2004】郁闷的出纳员

    Splay Splay的模板题吧……妥妥的序列操作= =(好像有段时间没写过这种纯数据结构题了……) /************************************************ ...

  10. Hdu 1507 Uncle Tom's Inherited Land* 分类: Brush Mode 2014-07-30 09:28 112人阅读 评论(0) 收藏

    Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...