程序员数据结构和算法分析

JAVA反射机制

2018-11-01  本文已影响15人  coder_flag

一、什么叫反射?

首先给个定义:

    JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

   什么意思呢,简单来说就是通过反射,我们在程序运行时可以获得程序或者程序集中每一个类型的成员和成员信息。
   java程序中的一般的对象的类型都是在编译期就确定了下来,而java的反射机制可以动态地(在运行期)创建对象并调用其属性,这里创建的对象的类型在编译期是未知的。

反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。

反射机制提供的功能:

1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
4.在运行时调用任意一个对象的方法



二、反射的用途

那么说了一堆,反射的到底能干什么呢?

在java EE 的世界里,反射机制最大的作用就是支持==以声明式的方法(在XML中)来描述应用的行为==,是Struts,Spring ,Hibernate 核心技术之一。

举个栗子:
【Struts的例子:】在运用Struts 2框架的开发中我们一般会在struts.xml里去配置Action,比如:

  1. 在XML配置文件中定义Action
<action name="HelloWorld" class="example.HelloWorld">        
        <result>/hello.jsp</result>  
</action
  1. 定义Java 类
public class HelloWorld extends ExampleSupport {  

    public String execute() throws Exception {    

        ......

        return SUCCESS;                           

    }  

    .......

}

配置文件与Action建立了一种映射关系,当View层发出请求时,请求会被StrutsPrepareAndExecuteFilter拦截,然后StrutsPrepareAndExecuteFilter会去动态地创建Action实例。

Struts 框架的作者事先肯定不知道你会配置一个HelloWorld的Action 。

不过他可以这么做, Struts 在启动以后,解析你配置XML配置文件, 发现名称为HelloWorld的Action, 找到相对于的类名example.HelloWorld, 然后就可以通过反射去实例化这个类。 等到有人调用这个action 的时候, 可以通过反射来调用HelloWorld的execute() 方法。


三、反射基础:关于class类

1、Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Method,描述字段的Filed,描述构造器的Constructor等属性

2、对象照镜子后(反射)可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。

3、对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个Class对象包含了特定某个类的有关信息。

4、Class 对象只能由系统建立对象

5、一个类在 JVM 中只会有一个Class实例

//总结一下就是,JDK有一个类叫做Class,这个类用来封装所有Java类型,包括这些类的所有信息,JVM中类信息是放在方法区的。

//所有类在加载后,JVM会为其在堆中创建一个Class<类名称>的对象,并且每个类只会有一个Class对象,这个类的所有对象都要通过Class<类名称>来进行实例化。

//上面说的是JVM进行实例化的原理,当然实际上在Java写代码时只需要用 类名称就可以进行实例化了。

//总结一下就是,JDK有一个类叫做Class,这个类用来封装所有Java类型,包括这些类的所有信息,JVM中类信息是放在方法区的。

//所有类在加载后,JVM会为其在堆中创建一个Class<类名称>的对象,并且每个类只会有一个Class对象,这个类的所有对象都要通过Class<类名称>来进行实例化。

//上面说的是JVM进行实例化的原理,当然实际上在Java写代码时只需要用 类名称就可以进行实例化了。

public final class Class<T> implements java.io.Serializable,
                          GenericDeclaration,
                          Type,
                          AnnotatedElement {
虚拟机会保持唯一一
            //通过类名.class获得唯一的Class对象。
            Class<UserBean> cls = UserBean.class;
            //通过integer.TYPEl来获取Class对象
            Class<Integer> inti = Integer.TYPE;
          //接口本质也是一个类,一样可以通过.class获取
            Class<User> userClass = User.class;



四、反射的基本运用

一、使用反射机制创建实例,并调用其方法

示例类:

package com.example;

public class HelloWorld {

    public HelloWorld(){

    }

    public void sayHello(){

        System.out.println("hello world!");

    }

}

//第一步, 先把HelloWorld的类装载进来

Class cls = Class.forName("com.example.HelloWorld");

//第二步, 创建一个HelloWorld的实例, 注意, 这里并没有用强制转型把obj转成HelloWorld

Object obj = cls.newInstance();

//第三步, 得到这个类的方法, 注意, 一个类的方法也是对象啊

Method m = cls.getDeclaredMethod("sayHello");

//第四步, 方法调用, 输出"hello world"

m.invoke(obj);



二、更多基本应用:参考这里
1.判断是否为某个类的实例
2.获取某个class对象的方法集合
3.为某个class对象创建实例
4.获取构造器的信息
5.调用方法
6.获取class类的成员变量





文章主要参考:(谢谢!!!!!)

作者 :老刘 码农翻身

作者:程序员江湖

上一篇下一篇

猜你喜欢

热点阅读