java SE 反射机制
来源:互联网 发布:软件行业发展现状 编辑:程序博客网 时间:2024/05/16 19:21
反射
一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
编程时什么情况下才需要加载类,并解剖出类的各个组成部分呢?
Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的Field、Constructor、Method、Array类。
注意:Class类是Java反射的起源,针对任何一个你想探勘的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。
Class类
JVM为每种类型管理着一个独一无二的Class对象----每个类(型)都有一个Class对象。
Java程序运行过程中,当需要创建某个类的实例时,JVM首先检查所要加载的类对应的Class对象是否已经存在。如果还不存在,JVM就会根据类名查找对应的字节码文件并加载,接着创建对应的Class对象,最后才创建出这个类的实例。
系统对所有对象进行的运行时类型标识
Class类对象用来保存这些类型信息的
例如,
java基本数据类型(boolean、byte、char、short、int、long、float 和 double);
关键字void 也都对应一个 Class 对象;
每个数组属性也被映射为 Class 对象,所有具有相同类型和维数的数组都共享该 Class 对象。
因此,运行中的类或接口在JVM中都会有一个对应的Class对象存在,它保存了对应类或接口的类型信息。要想获取类或接口的相应信息,需要先获取这个Class对象。
加载类
Java中有一个Class类用于代表某一个类的字节码。
Class类即然代表某个类的字节码,它当然就要提供加载某个类字节码的方法:forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装
另外两种得到class对象的方式
类名.class: Manager.class; int.class; double[].class;
对象.getClass()
解剖类
Class对象提供了如下常用方法:
Public Constructor getConstructor(Class<?>... parameterTypes)
Public Method getMethod(String name, Class<?>... parameterTypes)
Public Field getField(String name) public
public Constructor getDeclaredConstructor(Class... parameterTypes)
public Method getDeclaredMethod(String name,Class... parameterTypes)
public Field getDeclaredField(String name)
这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、 Method 、 Field 对象表示。
思考:假设你是一个框架的设计者,解剖出这些成员后你会干什么?
利用Constructor创建对象
Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object... initargs)
initargs用于指定构造函数接收的参数
练习:反射类无参、有参、私有的构造函数,创建类的对象。
多学一招:sun公司为简化开发人员创建对象,它在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor 类以创建对象。
不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。
利用Method执行方法
Method对象提供了如下方法,用于执行它所代表的方法:
public Object invoke(Object obj,Object... args)
练习:使用Method分别执行无参、有参、多个参(带数组和基本数据类型)、静态、私有的方法。
jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object... args)
Jdk1.4:public Object invoke(Object obj,Object[] args),
利用Method执行main方法
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了
利用Field访问属性
Field对象提供了如下方法,用于设置、获取对象属性的值:
public void set(Object obj,Object value)
public Object get(Object obj)
- Java SE --- 反射机制
- java SE 反射机制
- 【Java SE】java反射机制
- java se 学习笔记 之 reflection(反射机制)1
- java se学习笔记 反射机制(上)
- java se反射
- Java Se---反射
- Java SE 基础:反射
- 【Java SE】反射
- Java SE 加强内省、反射
- JAVA SE——反射
- java se 学习笔记 之 reflection(反射机制之Array_1)2
- java se 学习笔记 之 reflection(反射机制之Array_2)3
- Java SE学习笔记-基础加强之类加载机制与反射
- 【反射】JAVA反射机制
- Java SE之异常机制
- 【JavaSE学习笔记】SE完结_反射机制,枚举Enum
- 【Java】JAVA反射机制
- 减小flex文件(swf)的方法
- 屏幕不光只看尺寸 各材质屏幕实战解析
- wcf 注册windows服务
- javascript面向对象编程封装
- HDU 1015 dfs回溯
- java SE 反射机制
- Mybatis自定义缓存——Redis实现
- 集成 Tomcat 插件到 Eclipse 的过程 .
- 流年,经不起怀念
- 2012天津赛区第六题---You Are the One(hdu4283)
- 找不到.classpath文件啊,新手求教!
- 查询IP地址
- Trident state
- response设置编码