反射机制一

        

目录

动态语言

反射机制的本质和 Class 类

反射机制的本质

java.lang.Class 类

获取 Class 类对象 3 种方式


        Java 反射机制是 Java 语言一个很重要的特性,它是 Java “动态性”的重要体现。反射机 制可以让程序在运行时加载编译期完全未知的类,让我们的程序更加灵活、更加开放。但是,反射机制的不足就是会大大降低程序执行的效率。

         反射机制在实际开发中直接使用的并不多,但是很多框架底层都会使用到反射机制。因 此,理解反射机制对于大家后面学习更加深入的知识非常必要。

动态语言

        动态语言是指在程序运行时,可以改变程序的结构或变量的类型。典型的动态语言有: Python、Ruby、JavaScript 等。

JavaScript 代码演示动态改变程序结构

function test(){
    var s = "var a=3;var b=5;alert(a+b);";
    eval(s);
}

        通过上面的代码,我们会发现 JavaScript 可以将字符串里面的源代码进行执行。也就是 说,外部传入的字符串是什么内容,我就执行什么;这样在执行的时候,完全改变了原来源 代码的结构。 这种动态性,让程序更加灵活,更加具有开放性。

        Java 语言虽然具有动态性,但是 Java 并不是动态语言。我们可以利用反射机制、字节 码操作获得类似动态语言的特性。

反射机制的本质和 Class 类

        学习反射机制基本就等同于学习 Class 类的用法!理解 Class 类也就是理解了反射机制。

        JAVA 反射机制让我们在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法; 这种动态获取的以及动态调用 对象的方法的功能就是“Java 的反射机制”。

反射机制的本质

        反射机制(Reflection ) 是 Java 动态性的重要体现。我们可以通过反射机制在运行时加载 编译期完全未知的类。通过反射机制,我们可以在运行时加载需要的类,从而动态的改变了 程序结构,使我们的程序更加灵活、更加开放。

        但是反射机制也有缺点,那就是效率问题。反射会大大降低程序的执行效率。同时,反 射机制绕过了源代码,也会给代码的维护增加困难。

        首先,我们先看一段极其简单的代码。这段代码创建了一个 User 对象,但是其内存结构到底是怎么样的呢?

创建 User 对象

public class Test01 {
    public static void main(String[] args) {
        User user = new User("王五");
    }
}

        实际上,我们在加载任何一个类时都会在方法区中建立“这个类对应的 Class 对象”,由 于“Class 对象”包含了这个类的整个结构信息,所以我们可以通过这个“Class 对象”来操作这 个类。

        我们要使用一个类,首先要加载类;加载完类之后,在堆内存中,就产生了一个 Class 类 型的对象(一个类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。我们可 以通过这个对象知道类的结构。这个对象就像一面镜子,透过这个镜子可以看到类的结构, 所以,我们形象的称之为:反射。因此,“Class 对象”是反射机制的核心。

通过 Class 类动态加载某个类

Class c = Class.forName("com.dlsfee.test.User");

        Class.forName()可以让我们在运行时再决定加载什么样的类,字符串传入什么类,我就 加载什么类,完全和源代码无关,这就是“动态性”。反射让我们实现了“运行时加载、探知、 使用,而编译期间完全未知的类”。

        反射机制的核心就是“Class 对象”。获得了 Class 对象,就相当于获得了类结构;我们可 以通过“Class 对象”调用这个类的所有属性、所有方法、构造方法;这样,我们就可以动态 加载、运行相关的类。

java.lang.Class 类

        java.lang.Class 类是反射(Reflection)的根源。针对任何您想动态加载、运行的类,唯 有 先 获 得 相 应 的 Class 对 象 。 java.lang.Class 类 十 分 特 殊 , 用 来 表 示 Java 中 类 型(class/interface/enum/annotation/primitive type/void)本身。

Class 类的对象如何获取?

1. 运用 getClass()

2. 运用.class 语法

3. 运用 Class.forName()(最常被使用)

获取 Class 类对象 3 种方式

/**
 * 测试获得Class对象的三种方式.
 */
public class Test01 {
    public static void main(String[] args) throws Exception {
        User user = new User("王五");
        Class c1 = user.getClass(); //方式一
        Class c2 = User.class; //方式二
        Class c3 = Class.forName("com.reflex.User"); //方式三
        System.out.println(c1 == c2); //true
        System.out.println(c1 == c3);//true
        //获取类的名字
        System.out.println(c1.getName()); //输出“包名+类名::com.reflex.User
        System.out.println(c1.getSimpleName()); //输出”类名“:User
    }
}

        由于系统针对每个类只会创建一个 Class 对象,因此,我们发现上面三个变量 c1/c2/c3 实际指向的是同一个对象。

  • 35
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值