java开发--反射技术
学习目标:
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.反射的例子:
点击(此处)折叠或打开
- public class ReflectTest {
- public static void main(String[] args){
- String name;
- if(args.length > 0){
- name = args[0];
- }else{
- Scanner in = new Scanner(System.in);
- System.out.println("Enter class name (e.g. java.util.Date): ");
- name = in.next();
- }
- try{
- //print class name and superclass name(if != Object)
- Class c1 = Class.forName(name);
- Class superc1 = c1.getSuperclass();
- String modifiers = Modifier.toString(c1.getModifiers());
- if(modifiers.length() > 0) System.out.print(modifiers+" ");
- System.out.print("class "+name);
- if(superc1 != null && superc1 != Object.class) System.out.println(
- " extends"+superc1.getName());
- System.out.print("\n{\n");
- printConstructors(c1);
- printMethods(c1);
- printFields(c1);
- System.out.println("}");
- }catch(ClassNotFoundException e){
- e.printStackTrace();
- }
- System.exit(0);
- }
- /*
- * prints all constructors of a class
- */
- public static void printConstructors(Class c1){
- Constructor[] constructors = c1.getConstructors();
- for(Constructor c:constructors){
- String name = c.getName();
- System.out.print(" ");
- String modifiers = Modifier.toString(c1.getModifiers());
- if(modifiers.length() > 0) System.out.print(modifiers+" ");
- System.out.print(name+"( ");
- //print parameter types
- Class[] paramTypes = c.getParameterTypes();
- for(int j=0; j<paramTypes.length; j++){
- if(j>0) System.out.print(", ");
- System.out.print(paramTypes[j].getName());
- }
- System.out.println("); ");
- }
- }
- /**
- * prints all methods of a class
- */
- public static void printMethods(Class c1){
- Method[] methods = c1.getMethods();
- for(Method m : methods){
- Class retType = m.getReturnType();
- String name = c1.getName();
- System.out.print(" ");
- //print modifiers,return type and method name
- String modifiers = Modifier.toString(m.getModifiers());
- if(modifiers.length() > 0) System.out.print(modifiers + " ");
- System.out.print(retType.getName() + " "+name+"(");
- //print parameter types
- Class[] paramTypes = m.getParameterTypes();
- for(int j = 0; j<paramTypes.length; j++){
- if(j>0) System.out.print(", ");
- System.out.print(paramTypes[j].getName());
- }
- System.out.println(");");
- }
- }
- /**
- * print all fields of a class
- */
- public static void printFields(Class c1){
- Field[] fields = c1.getDeclaredFields();
- for(Field f : fields){
- Class type = f.getType();
- String name = f.getName();
- System.out.print(" ");
- String modifiers = Modifier.toString(f.getModifiers());
- if(modifiers.length() > 0) System.out.print(modifiers+" ");
- System.out.println(type+" "+name+";");
- }
- }
- }
java开发--反射技术的更多相关文章
- Java的反射技术
什么是反射机制 Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能调用它的任意属性和方法.这种动态获取信息以及动态调用对象属性和方法的即使称为J ...
- Java采用反射技术创建对象后对目标类的成员变量和成员方法进行访问
实现: package com.ljy; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * * @Class ...
- Java通过反射技术动态创建对象(有参、无参构造)
实现类: package com.ljy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTarge ...
- 2015网易校招Java开发工程师(技术架构)在线笔试题
1. 程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process ...
- java开发常用技术
基础部分 1. 线程和进程的区别 线程三个基本状态:就绪.执行.阻塞 线程五个基本操作:创建.就绪.运行.阻塞.终止 进程四种形式:主从式.会话式.消息或邮箱机制.共享存储区方式 进程是具有一定功能的 ...
- 2015年网易校招Java开发工程师(技术架构)在线笔试题
1. 程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process ...
- java 使用反射技术解耦
1.调用的代码 /src/de/test.java package de; public class Test { public static void main(String[] args) { D ...
- java开发目前技术选型
目前系统采用 1.后端 服务框架:Dubbo.zookeeper 缓存:Redis.ehcache 消息中间件:ActiveMQ,kafka 负载均衡:Nginx 分布式文件:FastDFS 数据库连 ...
- Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框
原文出处:博主宇宙的极客http://www.cnblogs.com/nokiaguy/archive/2010/07/27/1786482.html 众所周知,AlertDialog类用于显示对话框 ...
随机推荐
- HMMPfam的安装使用手记(转载)
转载至:http://blog.sina.com.cn/s/blog_3f6403290100rb61.html(感谢原文作者) HMMPfam的安装使用手记前言 简要介绍一下 HMMPfam吧.这还 ...
- [SSH服务]——SSH端口转发
实验拓扑图 实验描述 假设有三台主机A.B.C.B和A.C可以连通,AC两台主机不能连通. 这时候可以用本地端口转发,来实现A和C通过B来连通. 实验中,为了构造上述环境,我们使用三台虚拟机,其网络环 ...
- Google Volley: How to send a POST request with Json data?
sonObjectRequest actuallyaccepts JSONObject as body. From http://arnab.ch/blog/2013/08/asynchronous- ...
- Log4Net学习【二】
Log4Net结构详解 当我们在描述为系统做日志这个动作的时候,实际上描述了3个点:做日志,其实就是在规定,在什么地方 用什么日志记录器 以什么样的格式做日志.把三个最重要的点抽取出来,即什么地方,日 ...
- 【收藏】win7打开word每次提示配置解决办法
打开“我的电脑”——“ C:\Program Files\Common Files\Microsoft Shared\OFFICE12\Office Setup Controller ”——找到一个“ ...
- <<梦断代码>>读书笔记
从任何角度,Chandler项目开始时都是值得羡慕的.虽然是讲一个软件项目是如何失败的,不过里面有让我觉得很有意思. 失败了就进行反思:定位不能逆时代的潮流, 互联网的趋势不可逆转,人员沟通与合作是永 ...
- Spring事务总结
事务是什么? 事务就是用来解决类似问题,事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败,那么事务就会回滚到最开始的状态,仿佛什么都没有发生过.在企业级应 ...
- Linux常用命令查看日志
cattail -f日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一 /var/log/secure 与安全相关的日 ...
- 重装系统必做之——更换Windows系统的默认临时文件的存储目录
作为一名计算机爱好者,重装电脑是家常便饭,但是重装电脑的目的无非就是: 1.操作系统更新换代: 2.系统速度太慢: 或者更多.... 我们大多数目的都是上述中第2点,有时候是否仅仅重装系统而忽略了一些 ...
- C++实现CString和string的互相转换
CString->std::string 例子: CString strMfc=“test“; std::string strStl; strStl=strMfc.GetBuffer(0); u ...