Java反射机制( JAVA Reflection)

来源:互联网 发布:数据库结构设计文档 编辑:程序博客网 时间:2024/06/05 03:11

首先有两个问题:

 1> 什么是Java的反射机制? 2> 反射机制有什么作用?
  • 1
  • 2
  • 1
  • 2

<1> 反射机制指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。


<2>反射能够让我们:

运行时检测对象的类型;动态构造某个类的对象;检测类的属性和方法,并调用;任意调用对象的方法;修改构造函数、方法、属性的可见性;

用处:

对于Web框架,开发人员在配置文件中定义他们对各种接口和类的实现。通过反射机制,


例如,Spring框架使用如下的配置文件:

<bean id="someID" class="com.programcreek.Foo">    <property name="someField" value="someValue" /></bean>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

当Spring容器处理元素时,会使用Class.forName(“com.programcreek.Foo”)来初始化这个类,并再次使用反射获取元素对应的setter方法,为对象的属性赋值。

Servlet也会使用相同的机制:

<servlet>    <servlet-name>someServlet</servlet-name>    <servlet-class>com.programcreek.WhyReflectionServlet</servlet-class><servlet>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

介绍三个对象的机制与实现:

类对象(Class类的某一个具体类对象) 
实例化对象(某一具体类的实例对象)


a. Class对象的机制与实现(假设已经存在普通类Book)

Class就是类的类型。IntegerString...这些类的类型就是Class
  • 1
  • 1
1 三种*类对象*的获取方式 Class cl1 (类的类型) = Class.forName("一个类的完整路径名")2 类的实例化对象来获取类对象 Object ob = new Book(); Class cl2 (类的类型) = ob.getClass();3 直接使用类.class Class cl3 = Book.class;     

通过类对象可以实例化一个对象

Book bk = (Book)cl1.newInstance();  //默认返回一个Object类的对象,实例化类对象,无参,无参。    
  • 1
  • 1

b. Field对象的机制与实现

Java.lang.reflect.Field类,用于表示类中,接口中属性对象的类。 
可以操作类中私有,以及公有等全部属性和属性的信息。

package com.java.test;import com.java.bean.Book;import java.lang.reflect.Field;public class TestField {    //使用传递过来的Class对象获取类中的属性    public void show(Class cls){        //数组中每一个Field对象都是Book的一个属性        Field[] fid = cls.getDeclaredFields();       //可以将私有属性获取到        //Field[] fid = cls.getFields();             //只能获取到公有属性        for (Field f : fid){            System.out.println(f.getName());            System.out.println(f.getType());        }    }    //该方法使用传递过来的实体类对象获取属性    public void show2(Object obj){        Class cls = obj.getClass();      //获取类对象,感觉还是回到了第一种方式        Field[] fid = cls.getDeclaredFields();        for (Field fi : fid){            try {                fi.setAccessible(true);   //可以理解为启用私有属性的访问权限                System.out.println(fi.getName()+"值: "+fi.get(obj));//get是将属性值取出来            } catch (IllegalAccessException e) {                e.printStackTrace();            }        }    }    public static void main(String[] args) {        Book bk = new Book();        bk.setId(1);        bk.setName("JVM虚拟机");        bk.setType("Java");        TestField tf = new TestField();        //tf.show(Book.class);        tf.show2(bk);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

c. Method对象的机制与实现 
Java.lang.reflect.Method类是用于表示类中,接口中方法对象的类。 
可以操作类中私有,以及公有…全部方法。

package com.java.test;import com.java.bean.Book;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class TestMethod {    //该方法用于获取对象的所有方法名称 返回值类型 以及参数信息    public void show(Object obj){        Class cls = obj.getClass();        Method[] me = cls.getDeclaredMethods();  //获取到Book类中所有的方法        for (Method m : me){            System.out.println("Name: "+m.getName());           //方法名            System.out.println("Type: "+ Modifier.toString(m.getModifiers()));      //方法修饰符            System.out.println("Return: "+m.getReturnType());   //方法返回值            Class[] praType = m.getParameterTypes();            //获取方法参数            System.out.println("params: ");            for (Class c : praType){                System.out.println(c.getName());            }        }        try {            Method mt = cls.getMethod("getName",null);   //获取到方法后进行调用            try {                //此处如果有多个参数的话,先把参数保存在数组(数组可以为Object类型)里。                mt.invoke(obj,new Object[0]);   //obj对象调用getName()方法,参数为null(有点反射的意思了呦)            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }        } catch (NoSuchMethodException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        Book bk = new Book();        bk.setId(1);        bk.setName("JVM虚拟机");        bk.setType("Java");        TestMethod tm = new TestMethod();        tm.show(bk);    }}
0 0
原创粉丝点击