黑马程序员-Java反射机制
2015-11-12 16:07
447 查看
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
!--概述和应用场景
1 概念:
Java的反射机制是在运行状态中,对于任意一个类(class文件),都能知道这个类的所有属性和方法,对于任意一个对象
,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能被称为Java语言的反射机制
总结:动态获取类的信息,就是反射机制
目的:反射的目的就是为了拿到类的字节码文件内容--Class
2:应用场景
一个应用程序,如果需要更新,那么怎么更新的呢?
那是因为应用程序启动前都会首先读取配置文件,比如Tomcat的Servlet
而我们要做的就是把通过继承应用程序暴露出来的接口的方式,把自定义的接口的子类放到配置.xml文件中,这样,应用程序会动态的加载并获取接口子类中的内容并调用
!--获取字节码文件对象的三种方式
1:new Object().getClass();//使用上帝类中的getClass()方法获得--通过对象获取
2:任意一个数据类型都具备一个静态的属性class--Object.class;
3:以上两种都还不够拓展
只要通过给定类的字符串名称就可以获得该类的字节码文件,这样更为拓展,可以用Class类中的方法完成,forName(类名)
!--首先定义一个可测试的类:
!--获取Class中的构造函数并实例化
步骤:
第一步:得到类名
第二步:根据类名创建该字节码文件对象
第三步(空参):直接调用Class对象的newInstance()方法返回一个Object对象--多态的应用
(有参):这就要使用到反射包java.lang.reflect包里面的Constructor类,再根据Constructor对象实例化字节码文件对象
如下:
!--获取Class文件中的字段
方法: 1:Field
返回一个
2:Field
返回一个
3:Field[]
返回一个包含某些
4:Field[]
返回
5;当通过上述方法获得相应字段后,就可以对该字段对象通过方法进行操作
Field对象的方法:
5.1:void
将指定对象变量上此
5.2:Object
返回指定对象上此
如下:
创建字节码文件对象不变,其他步骤如下:
第一步:获得方法--Method clazz.
返回一个
第二步:调用方法--Object new Method(...).
表示字节码文件对象的实例,
args 不在是数据类型的class形式,而是传入对应值。。。
对带有指定参数的指定对象调用由此
补充:获得本类中所有公共的方法:clazz.getMethods();
获取本类中所有的方法:clazz.getDeclaredMethods();
如下:
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
!--概述和应用场景
1 概念:
Java的反射机制是在运行状态中,对于任意一个类(class文件),都能知道这个类的所有属性和方法,对于任意一个对象
,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能被称为Java语言的反射机制
总结:动态获取类的信息,就是反射机制
目的:反射的目的就是为了拿到类的字节码文件内容--Class
2:应用场景
一个应用程序,如果需要更新,那么怎么更新的呢?
那是因为应用程序启动前都会首先读取配置文件,比如Tomcat的Servlet
而我们要做的就是把通过继承应用程序暴露出来的接口的方式,把自定义的接口的子类放到配置.xml文件中,这样,应用程序会动态的加载并获取接口子类中的内容并调用
!--获取字节码文件对象的三种方式
1:new Object().getClass();//使用上帝类中的getClass()方法获得--通过对象获取
2:任意一个数据类型都具备一个静态的属性class--Object.class;
3:以上两种都还不够拓展
只要通过给定类的字符串名称就可以获得该类的字节码文件,这样更为拓展,可以用Class类中的方法完成,forName(类名)
!--首先定义一个可测试的类:
public class Person { public String sex; private String name;//姓名 private int age;//年龄 public Person(){};//空参数 /** * 有参构造函数 * @param name * @param age */ public Person(String name,int age){ this.name=name; this.age=age; System.out.println(name+"有参的构造函数"+age); } /** * 无参方法 */ public void show(){ System.out.println(name+"--无参方法---"+age); } /** * 带参方法 * @param info */ public void paraShow(String info){ System.out.println(info+"----"+name+age); } /** * 私有方法 */ private void privateShow(){ System.out.println("私有方法"); } }
!--获取Class中的构造函数并实例化
步骤:
第一步:得到类名
第二步:根据类名创建该字节码文件对象
第三步(空参):直接调用Class对象的newInstance()方法返回一个Object对象--多态的应用
(有参):这就要使用到反射包java.lang.reflect包里面的Constructor类,再根据Constructor对象实例化字节码文件对象
如下:
import java.lang.reflect.Constructor; /** * !--Java反射机制概述:应用场景 * @author Administrator * */ public class ReflexOverViewDemo { public static void main(String[] args) throws Exception{ getMethod_1(); } /** * 获取Class中的构造函数 */ private static void getMethod_1() throws Exception{ //第一步:获得该类Class对象 Class clazz=Class.forName("reflex.Person");//必须指定包名 //第二步:导入反射包,声明构造方法 Constructor constructor=clazz.getConstructor(String.class,int.class); //第三步:获得该构造方法的Class实例 Object obj=constructor.newInstance("小王",19); } }
!--获取Class文件中的字段
方法: 1:Field
getField(String name)
返回一个
Field对象,它反映此
Class对象所表示的类或接口的指定公共成员字段。
2:Field
getDeclaredField(String name)//任意权限的字段
返回一个
Field对象,该对象反映此
Class对象所表示的类或接口的指定已声明字段。
3:Field[]
getFields()
返回一个包含某些
Field对象的数组,这些对象反映此
Class对象所表示的类或接口的所有可访问公共字段。
4:Field[]
getDeclaredFields()
返回
Field对象的一个数组,这些对象反映此
Class对象所表示的类或接口所声明的所有字段。
5;当通过上述方法获得相应字段后,就可以对该字段对象通过方法进行操作
Field对象的方法:
5.1:void
set(Object obj,Object value)//这里Object表示的是任意的字节码文件对象实例
将指定对象变量上此
Field对象表示的字段设置为指定的新值。
5.2:Object
get(Object obj)//这里的Object--是多态的用法,可以得到对应字段的值
返回指定对象上此
Field表示的字段的值。
如下:
import java.lang.reflect.Field; /** * 获得Class中的字段 * @author Administrator * */ public class ReflexGetField { public static void main(String[] args) throws Exception{ getField(); /*Person p=new Person(); Class c=Person.class;*/ } private static void getField() throws Exception { Class clazz=Class.forName("reflex.Person");//必须指定包名 //获得某一个公共字段 Field f=clazz.getField("sex"); System.out.println(f); //获取全部公共字段 Field[] ff=clazz.getFields(); for(Field fi : ff){ System.out.println(fi); } //获取任意权限的字段 Field fd=clazz.getDeclaredField("name"); System.out.println(fd); //获得全部的字段 Field []fds=clazz.getDeclaredFields(); for(Field fid : fds){ System.out.println(fid); } //获得实例 Object obj=clazz.newInstance(); f.set(obj,"男");//都是某个字段针对某个对象的操作 Object o=f.get(obj);//返回Object类型--多态 System.out.println(o); } }!--获取Class中的函数
创建字节码文件对象不变,其他步骤如下:
第一步:获得方法--Method clazz.
getMethod(String name,Class<?>... parameterTypes)//如果无参的方法,Class<?>处就写null,记住:参数都是指定数据类型的class形式
返回一个
Method对象,它反映此
Class对象所表示的类或接口的指定公共成员方法。
第二步:调用方法--Object new Method(...).
invoke(Object obj,Object... args)//这里obj
表示字节码文件对象的实例,
args 不在是数据类型的class形式,而是传入对应值。。。
对带有指定参数的指定对象调用由此
Method对象表示的底层方法。
补充:获得本类中所有公共的方法:clazz.getMethods();
获取本类中所有的方法:clazz.getDeclaredMethods();
如下:
import java.lang.reflect.*; /** * 获得Class中的方法 * @author Administrator * */ public class ReflexGetMethod { public static void main(String[] args)throws Exception { getMethods(); } private static void getMethods() throws Exception{ // TODO Auto-generated method stub Class clazz=Class.forName("reflex.Person");//必须指定包名 //获得对应参数列表的对应方法,空参数用null补 Method m=clazz.getMethod("show",null);//导入反射包 System.out.println(m); //带参的方法--参数列表是对应的数据类型的Class表现形式 Method mp=clazz.getMethod("paraShow",String.class); System.out.println(mp); //获取Class中所有公共方法,包括从父类中继承的方法 Method[]methods=clazz.getMethods(); for(Method md : methods){ System.out.println(md); } //获取本类的所有方法,包含私有 Method[]methodsd=clazz.getDeclaredMethods(); for(Method md : methodsd){ System.out.println(md); } //创建一个有参构造函数的对象 Constructor constructor=clazz.getConstructor(String.class,int.class); Object obj=constructor.newInstance("张三",23);//注意获得实例的顺序 //调用方法--必须对象才能调用方法 //Object obj=clazz.newInstance(); m.invoke(obj,null); mp.invoke(obj,"传入的"); } }总结:反射是很重要的比分,它为应用程序自定义处理请求和应答提供了技术支持
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
相关文章推荐
- 疯狂Java程序员16堂课---第8课:异常捕捉的陷
- 黑马程序员——OC基础02—封装、继承、多态
- Java程序员到架构师的推荐阅读书籍
- 老程序员的10条告诫
- 15个IT程序员必须思考的问题
- ——黑马程序员——OC中集合对象的内存管理及copy的用法
- 高端ios面试总结
- 新浪也遇寒冬:全面停止社招—兄弟连IT教育
- 程序员的修炼
- 系统设计的高频面试题都有哪些?
- 编程面试过程中常见的10大算法概念汇总(Java版)
- 【转】老程序员的忠告:不要做浮躁的软件工程师
- 黑马程序员——OC基础01—类和对象
- JAVA面试题大全
- Android 面试精华题目总结
- 高效程序员的 7 个共同特征
- 百度面试题
- 面试题07-内存管理
- 面试题06-Foundation
- 程序员必备技能