V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ivito
V2EX  ›  程序员

关于反射的解释

  •  
  •   ivito ·
    fireboyvt · 2015-06-29 22:56:42 +08:00 via iPhone · 4284 次点击
    这是一个创建于 3420 天前的主题,其中的信息可能已经有所发展或是发生改变。
    看了几篇关于java反射的文章,概括一下就是使用字符串类型的类名获取类的信息,比如构造函数,元素等。但依然有些地方不太明白,反射的名称是怎么来的,有什么说法吗,没有直观的看出来啊
    19 条回复    2015-08-28 06:45:28 +08:00
    reeco
        1
    reeco  
       2015-06-29 23:21:05 +08:00
    reflection 的翻译
    ChanneW
        2
    ChanneW  
       2015-06-29 23:25:58 +08:00
    名称随便怎么来的都行,可以是默认指定的,可以是 xml里配置的,可以是前台请求的字符串。反射就是提供了另外一种调用方式,常见是用来让框架来调用用户的类的方法,反射让框架有一个通用的性的方式调用用户程序。
    SoloCompany
        3
    SoloCompany  
       2015-06-30 02:02:26 +08:00   ❤️ 2
    java.lang.reflection

    java 是静态语言,reflection 则反映的是其动态特性
    因为 reflection 特性所反映的也刚好和编码 - 编译 - 运行相反的过程,是在运行过程中反向获取源代码级别(并不完全等同于是源代码)的信息,并不是你所理解的简单的使用字符串获取类名,就找一个很简单的反例,Object.getClass() 就不需要任何字符串参数
    mfaner
        4
    mfaner  
       2015-06-30 04:17:19 +08:00
    reflection,以及另一个Mirror API,这两个命名以前就见被人喷过
    ivito
        5
    ivito  
    OP
       2015-06-30 08:31:55 +08:00
    @ChanneW
    @mfaner
    命名确实很没水平
    timi
        6
    timi  
       2015-06-30 08:59:33 +08:00
    大概就像镜子一样,能看到你之前(用C的时候)看不到的信息吧
    之前就是这样理解的,感觉3楼说的有道理
    ivito
        7
    ivito  
    OP
       2015-06-30 09:14:25 +08:00
    @SoloCompany Object.getClass()使用的前提是已经获得了Object对象,不能算作动态特性吧,感觉跟反射也不沾边啊
    jaycee110905
        8
    jaycee110905  
       2015-06-30 09:14:38 +08:00
    3楼说的很棒,学习了
    ivito
        9
    ivito  
    OP
       2015-06-30 09:16:05 +08:00
    @SoloCompany 我说的是通过字符串类型的类名获得类,你举的例子明显是用对象Object获得类了。
    ivito
        10
    ivito  
    OP
       2015-06-30 09:19:28 +08:00
    @SoloCompany 关于反射的解释很有那么点意思,不错
    clino
        11
    clino  
       2015-06-30 10:17:10 +08:00
    倒影 自省 镜面反射 反照
    repus911
        12
    repus911  
       2015-06-30 10:19:09 +08:00
    我倒是觉得命名挺好的
    agate
        13
    agate  
       2015-06-30 10:29:22 +08:00
    @SoloCompany 解释的很好啊
    zhaoqing256
        14
    zhaoqing256  
       2015-06-30 12:50:44 +08:00
    @SoloCompany 说得好啊
    hitsmaxft
        15
    hitsmaxft  
       2015-06-30 22:32:36 +08:00
    一般写代码是这样的 this.getClasss()
    运行时是这样的

    ALOAD 0
    INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;

    (因为 getClass 方法是从 Object 继承来的)

    编译的时候, javac 会自动帮你类型信息补充上, 所以说 java 是静态类型, 写的时候已经决定了类型信息。

    但是如果希望动态地在类型本身做一些操作,比如根据传入实例的具体类型, 调用指定的方法之类的。
    这时候就需要借助 reflection 系列包

    在java 中 ClassA 本身也是个类型, 通过加载器保证单例(所以。。。),ClassA.class 可以认为是 ClassA 类型在内存的单例。

    这个留给程序员的后门,就是通过字符串。 你写在代码里的是字符串, javac 会编译成 jvm 认得的类信息,而当人肉地通过反射告诉 jvm 的时候, 也是通过字符串, 所以你就看到用字符串查找 class,用字符串查找方法等等。

    总之, 你理解为你用反射其实就是人肉地在运行时干 javac 干的事情。

    在 java 里面,几乎都是以对象在处理事情。 所以使用反射的时候, 就是通过反射查找一个具体的类型或者具体的方法“的实例”, 然后调用这个实例的接口,来完成模拟 jvm 的行为。

    我不知道为什么叫做反射, 但是你可以认为用代码来描述代码, 或者看起来还像是照妖镜下的代码。
    shiznet
        16
    shiznet  
       2015-07-01 09:13:12 +08:00
    推荐题主看一下Java里的动态代理的实现,会对反射有更深的理解了
    ivito
        17
    ivito  
    OP
       2015-07-02 09:04:00 +08:00
    @hitsmaxft 很全面的解释,赞一个。其中提到的ClassA本身也是个类型,类型是指的元类吗?即类的类,ClassA只是元类的一个实例?
    ivito
        18
    ivito  
    OP
       2015-07-02 09:13:29 +08:00
    hitsmaxft
        19
    hitsmaxft  
       2015-08-28 06:45:28 +08:00 via iPhone
    @ivito 笔误 ClassA 也是存在对应的实例(或者说 object )
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   996 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:49 · PVG 03:49 · LAX 11:49 · JFK 14:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.