关于Java中反射的认识

  • Post author:
  • Post category:java


首先讲一下,以下的内容,源自下面的连接,关于反射,讲得很清楚,我也只是根据链接中的内容,加一点自己的理解.写一下。


java反射



引出反射

先给一个Hello类:

package com.mi.beans;

public class Hello {
    private String name;

    public Hello() {
        // TODO Auto-generated constructor stub
    }

    public void sayHello() {
        System.out.println("hello");
    }
}


下面是要求:


1.实例化Hello类,但是不能使用Hello hello = new Hello()来实例化。

2.调用Hello类中的sayHello方法,但是不能直接使用Hello的实例来调用。

在这里,就用到了反射了.下面是代码:

package com.mi.test;

import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) {
        try {
            Class claz = Class.forName("com.mi.beans.Hello");
            Object obj = claz.newInstance();
            Method method = claz.getDeclaredMethod("sayHello");
            method.invoke(obj);

        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}

说一下代码里涉及到的几个方法和类:


1.Class类

  • Class类也是java中的一个类,隶属于lang包下。只是和关键字class长相相似。而java是大小写敏感的。
  • Class类的对象内容是你创建的类的类型信息,比如你创建一个shapes类,那么,Java会生成一个内容是shapes的Class类的对象
  • Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。所以不能像普通类一样,通过New来创建对象。


2.forName()


  • 参数

    :className – 所需类的

    完全限定名


  • 返回值

    :具有指定名的类的 Class 对象。


3.newInstance()


返回值

:此对象所表示的类的一个新分配的实例。Object类型

也就是创建一个对象。


4.getDeclaredMethod()

  • 参数:name – 方法名

    parameterTypes – 参数数组
  • 返回值:该类与指定名和参数相匹配的方法的

    Method 对象

    ,需要Method对象来接收。

也就是拿到该对象的某个方法,方法的参数用来找到这个方法,包括方法名,和方法参数。找到唯一的一个方法。


5.Method类


存放方法的类,方法也是对象。所以需要对方法进行操作。


6.invoke();


  • 参数

    :obj – 从中调用底层方法的对象

    args – 用于方法调用的参数

  • 返回值

    :使用参数 args 在 obj 上指派该对象所表示方法的结果

也就是执行某个方法,注意是Method对象调用该方法.该方法的参数中有被执行方法的方法名以及参数列表。用以执行某一个具体的方法。



实例


上面是使用反射所需要到的最基本的东西,下面举一个应用中的实例:【spring】中的反射。前两天在学spring框架,只是会一点使用而已,对一些原理性的东西还不是很懂.借此机会,也深入的了解一下底层的东西。下面是具体的代码:


1. 创建一个Bean:

public  class   Hello
{
    private String message;
    public void setMessage(String message){
        this.message  = message;
    }
    public void getMessage(){
        System.out.println("My Message : "+ message);
    }
}


2. 配置信息


下面是在spring的配置文件中,通过set注入的方式对Hello类中的字段进行赋值.前提是你的实体类中的字段有get/set方法.

<bean id="hello"class="com.mi.beans.Hello">
    <propertyname="message"value="Hello World!"/>
</bean>


3.调用

ApplicationContext context =newClassPathXmlApplicationContext("Beans.xml");
Hello hello = (Hello) context.getBean("hello");
hello.getMessage();

上面的代码,可以想到它的底层应该是这样实现的:

1.通过参数中的Beans.xml文件,解析xml文件中的信息.

2.根据xml文件中的信息,包括类名/字段/,通过反射创建对象.

3.再通过反射,调用set方法或者get方法,这样你就能拿到最后的结果了.


newClassPathXmlApplicationContext()源代码



总结


反射最大的作用就是:

以申明式的方式(xml或注解)来描述应用的行为

。也就是不用把一切的东西写死,而是可以变化地来操作,极大的增强了编程时的灵活性。

简单的来讲, 反射能让你在

运行时而不是编程时

做下面的事情:

(1) 获取一个类的内部结构信息(或者称为元数据), 包括包名,类名, 类所有的方法。

(2) 运行时对一个Java对象进行操作, 包括创建这个类的实例, 设置一个属性的值, 调用这个类的方法等等。

(对了,我们经常使用MyEclipse也是使用了反射,才可以给出我们相对应的提示信息的,反射无处不在啊!)



版权声明:本文为MPFLY原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。