java的反射
2015-08-06 14:49
573 查看
java反射
先看一下定义:主要指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
有点绕,解释一下,就是在程序中,我们不需要用new来创建一个对象,而是通过类的父类Class来获取,这样做的好处就是使程序更加灵活,在设计模式中有很大的用处。
我们平时编写的类也是一个对象,类是java.lang.Class类的实例对象。可以认为:
There is a class named Class。
任何一个类都是Class类的实例对象,这个实例对象有三种表示方式。
首先,假设这有一个类class Foo{}
实例化一下 Foo foo1=new Foo();
任何一个类都有一个隐含的静态成员变量class
Class c1=Foo.class;
已知该类的对象通过getClass方法
Class c2=foo1.getClass();
官网上说c1,c2是Foo类的类类型。万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们称为该类的类类型。
注意:一个类只可能是CLass类的一个实例,也就是c1==c2.
使用Class.forName()
Class c3=Class.forName(“com.example.foo”);
我们可以通过类的类类型来创建该类的实例对象。
Foo foo2=(Foo)c1.newInstance();
该类必须有一个无参的构造函数,才能使用newInstance();
类的两种加载方式:
1. 静态加载:
new 创建对象是静态加载类,在编译时刻加载所有可能用到的类。
2. 动态加载
功能性的类,加载时最好使用动态加载。在运行时加载,使用接口编程。
二、方法的反射
三、成员变量的反射
四、构造函数的反射
测试方法:
测试结果:
五、方法的反射操作
method.invoke(对象,参数列表)
测试结果:
学会反射对我们以后的java学习有很大的帮助,能更好的让我们理解当下java的流行框架。现在很多公司用的框架都是自己写的,这时候就要用到反射了。javaweb中的常见框架struts2、hibernate、spring等都用到了反射。
先看一下定义:主要指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
有点绕,解释一下,就是在程序中,我们不需要用new来创建一个对象,而是通过类的父类Class来获取,这样做的好处就是使程序更加灵活,在设计模式中有很大的用处。
一、Class类
我们在面向对象编程中,可以认为万事万物皆对象(就是基本数据类型——java中也有封装的基本数据类型类)。我们平时编写的类也是一个对象,类是java.lang.Class类的实例对象。可以认为:
There is a class named Class。
任何一个类都是Class类的实例对象,这个实例对象有三种表示方式。
首先,假设这有一个类class Foo{}
实例化一下 Foo foo1=new Foo();
任何一个类都有一个隐含的静态成员变量class
Class c1=Foo.class;
已知该类的对象通过getClass方法
Class c2=foo1.getClass();
官网上说c1,c2是Foo类的类类型。万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们称为该类的类类型。
注意:一个类只可能是CLass类的一个实例,也就是c1==c2.
使用Class.forName()
Class c3=Class.forName(“com.example.foo”);
我们可以通过类的类类型来创建该类的实例对象。
Foo foo2=(Foo)c1.newInstance();
该类必须有一个无参的构造函数,才能使用newInstance();
类的两种加载方式:
1. 静态加载:
new 创建对象是静态加载类,在编译时刻加载所有可能用到的类。
2. 动态加载
功能性的类,加载时最好使用动态加载。在运行时加载,使用接口编程。
二、方法的反射
[code]/** * 获取成员函数信息 * @param obj 该对象所属类的信息 */ public static void printClassMethods(Object obj){ //要获取类的信息 首先要获取类的类类型 Class c1=obj.getClass();//传递的是哪个子类的对象 c1就是该子类的类类型 //获取类的名称 System.out.println("类的名称是:"+c1.getName()); /* * Method类,方法对象 * 一个成员方法就是一个Method对象 * getMethods()方法获取的是所有的public的函数,包括父类继承而来的 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 */ Method[] ms=c1.getMethods(); //c1.getDeclaredMethods(); for (Method method : ms) { //得到方法的返回值类型的类类型 Class returnType=method.getReturnType(); System.out.print(returnType.getSimpleName()+" "); //得到方法的名称 System.out.print(method.getName()+"("); //获取参数类型--->得到的是参数列表的类型的类类型 Class[] paramType=method.getParameterTypes(); for (Class class1 : paramType) { System.out.print(class1.getSimpleName()+","); } System.out.println(")"); } }
三、成员变量的反射
[code]/** * 获取成员变量的信息 * @param obj */ public static void printClassField(Object obj){ Class c=obj.getClass(); /* * 成员变量也是对象 * java.lang.reflect.Field 封装了关于成员变量的操作 * getFields()方法获取的是所有的public的成员变量的信息 * getDeclaredFields获取的是该类自己声明的成员变量的信息 */ //Field[] fs = c.getFields(); Field[] fs=c.getDeclaredFields(); for (Field field : fs) { //得到成员变量的类型的类类型 Class fieldType=field.getType(); //得到成员变量的名称--->field.getName() System.out.println(fieldType.getSimpleName()+" "+field.getName()); } }
四、构造函数的反射
[code]/** * 获取构造函数的信息 * @param obj */ public static void printClassConstructor(Object obj){ Class c=obj.getClass(); /* * 构造函数也是对象 * java.lang. Constructor中封装了构造函数的信息 * getConstructors获取所有的public的构造函数 * getDeclaredConstructors得到所有的构造函数 */ // Constructor[] cons=c.getConstructors(); Constructor[] cons=c.getDeclaredConstructors(); for (Constructor constructor : cons) { //获取构造函数的参数列表--->得到的是参数列表的类类型 Class[] paramType=constructor.getParameterTypes(); System.out.print(constructor.getName()+"("); for (Class class1 : paramType) { System.out.print(class1.getSimpleName()+","); } System.out.println(")"); } }
测试方法:
[code]public class TestDemo { public static void main(String[] args) { String str="hello"; ClassUtils.printClassMethods(str); ClassUtils.printClassField(str); ClassUtils.printClassConstructor(str); } }
测试结果:
[code]类的名称是:java.lang.String boolean equals(Object,) …… java.lang.String(StringBuffer,) java.lang.String(int,int,char[],)
五、方法的反射操作
method.invoke(对象,参数列表)
[code]package com.example.young; import java.lang.reflect.Method; public class TestDemo { public static void main(String[] args) { /* String str="hello"; ClassUtils.printClassField(str); ClassUtils.printClassMethods(str); ClassUtils.printClassConstructor(str); */ //通过反射操作类的方法 A a1 = new A(); //1、获取类的类类型 Class c=a1.getClass(); try { /*2.获取方法 名称和参数列表决定 getMethod获取的是public的方法 getDelcaredMethod自己声明的方法*/ Method m=c.getMethod("print", int.class ,int.class); //方法如果没有返回值返回null,有返回值返回具体的返回值 Object obj=m.invoke(a1,2,3); Method m2=c.getMethod("print", new Class[]{String.class,String.class}); Object obj1=m2.invoke(a1, "hello"," world"); } catch (Exception e) { e.printStackTrace(); } } } class A{ public void print(){ System.out.println("hello"); } public void print(int a,int b){ System.out.println(a+b); } public void print(String a,String b){ System.out.println(a+b); } }
测试结果:
[code]5 hello world
学会反射对我们以后的java学习有很大的帮助,能更好的让我们理解当下java的流行框架。现在很多公司用的框架都是自己写的,这时候就要用到反射了。javaweb中的常见框架struts2、hibernate、spring等都用到了反射。
相关文章推荐
- java 对象序列化
- Java泛型
- maven的安装和配置(手动和eclipse插件)
- java加密解密技术--DES算法
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- 高性能、高流量Java Web站点打造的22条建议
- java.lang.UnsupportedClassVersionError异常
- Spring.Net学习笔记七(集合类型的注入)
- Struts工作流程
- Android Studio之导入Eclipse项目
- Java中的static关键字解析
- Ehcache 整合Spring 使用页面、对象缓存
- java打包成jar
- java实现hash一致性算法
- java中线程池ExecutorService 线程管理
- springMVC学习笔记---注解启用基本配置
- Mac OS中配置java环境
- (转载) Java多线程技术
- java 利用内部类进行特别初始化
- Java无参构造方法