`

【转载】候捷谈Java反射机制

阅读更多

摘要<o:p></o:p>

Reflection Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fieldsmethods的所有信息,并可于运行时改变fields内容或唤起methods。本文借由实例,大面积示范Reflection APIs<o:p></o:p>

<o:p> </o:p>

关于本文:<o:p></o:p>

读者基础:具备Java 语言基础。<o:p></o:p>

本文适用工具:JDK1.5<o:p></o:p>

<o:p> </o:p>

关键词:<o:p></o:p>

Introspection(内省、内观)<o:p></o:p>

Reflection(反射)<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而动态一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。<o:p></o:p>

<o:p> </o:p>

一般而言,开发者社群说到动态语言,大致认同的一个定义是:程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,PerlPythonRuby是动态语言,C++JavaC#不是动态语言。<o:p></o:p>

<o:p> </o:p>

尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是反射、映象、倒影,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种看透class的能力(the ability of the program to examine itself)被称为introspection内省、内观、反省)。Reflectionintrospection是常被并提的两个术语。<o:p></o:p>

<o:p> </o:p>

Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个运行时才获知名称的class生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的MethodFieldConstructor等等classes<o:p></o:p>

<o:p> </o:p>

Classclass<o:p></o:p>

众所周知Java有个Object class,是所有Java classes的继承根源,其内声明了数个应该在所有Java class中被改写的methodshashCode()equals()clone()toString()getClass()等。其中getClass()返回一个Class object<o:p></o:p>

<o:p> </o:p>

Class class十分特殊。它和一般classes一样继承自Object,其实体用以表达Java程序运行时的classesinterfaces,也用来表达enumarrayprimitive Java typesboolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()JVM调用,JVM 便自动产生一个Class object。如果您想借由修改Java标准库源码来观察Class object的实际生成时机(例如在Classconstructor内添加一个println()),不能够!因为Class并没有public constructor(见1)。本文最后我会拨一小块篇幅顺带谈谈Java标准库源码的改动办法。<o:p></o:p>

<o:p> </o:p>

ClassReflection故事起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs。这些APIs将在稍后的探险活动中一一亮相。<o:p></o:p>

<o:p> </o:p>

#001 public final<o:p></o:p>

#002 class Class<T> implements java.io.Serializable,<o:p></o:p>

#003 java.lang.reflect.GenericDeclaration,<o:p></o:p>

#004 java.lang.reflect.Type,<o:p></o:p>

#005 java.lang.reflect.AnnotatedElement {<o:p></o:p>

#006    private Class() {}<o:p></o:p>

#007    public String toString() {<o:p></o:p>

#008        return ( isInterface() ? "interface " :<o:p></o:p>

#009        (isPrimitive() ? "" : "class "))<o:p></o:p>

#010    + getName();<o:p></o:p>

#011 }<o:p></o:p>

...<o:p></o:p>

1Class

分享到:
评论
1 楼 狂放不羁 2007-08-11  
“Class” object的取得途径

Java允许我们从多种管道为一个class生成对应的Class object。图2是一份整理。

Class object 诞生管道
示例

运用getClass()

注:每个class 都有此函数
String str = "abc";

Class c1 = str.getClass();

运用

Class.getSuperclass()2
Button b = new Button();

Class c1 = b.getClass();

Class c2 = c1.getSuperclass();

运用static method

Class.forName()

(最常被使用)
Class c1 = Class.forName ("java.lang.String");

Class c2 = Class.forName ("java.awt.Button");

Class c3 = Class.forName ("java.util.LinkedList$Entry");

Class c4 = Class.forName ("I");

Class c5 = Class.forName ("[I");

运用

.class 语法
Class c1 = String.class;

Class c2 = java.awt.Button.class;

Class c3 = Main.InnerClass.class;

Class c4 = int.class;

Class c5 = int[].class;

运用

primitive wrapper classes

的TYPE 语法


Class c1 = Boolean.TYPE;

Class c2 = Byte.TYPE;

Class c3 = Character.TYPE;

Class c4 = Short.TYPE;

Class c5 = Integer.TYPE;

Class c6 = Long.TYPE;

Class c7 = Float.TYPE;

Class c8 = Double.TYPE;

Class c9 = Void.TYPE;



图2:Java 允许多种管道生成Class object。



Java classes 组成分析

首先容我以图3的java.util.LinkedList为例,将Java class的定义大卸八块,每一块分别对应图4所示的Reflection API。图5则是“获得class各区块信息”的程序示例及执行结果,它们都取自本文示例程序的对应片段。



package java.util;                      //(1)

import java.lang.*;                     //(2)

public class LinkedList<E>              //(3)(4)(5)

extends AbstractSequentialList<E>       //(6)

implements List<E>, Queue<E>,

Cloneable, java.io.Serializable         //(7)

{

private static class Entry<E> { … }//(8)

public LinkedList() { … }           //(9)

public LinkedList(Collection<? extends E> c) { … }

public E getFirst() { … }           //(10)

public E getLast() { … }

private transient Entry<E> header = …;  //(11)

private transient int size = 0;

}

图3:将一个Java class 大卸八块,每块相应于一个或一组Reflection APIs(图4)。



Java classes 各成份所对应的Reflection APIs

图3的各个Java class成份,分别对应于图4的Reflection API,其中出现的Package、Method、Constructor、Field等等classes,都定义于java.lang.reflect。

Java class 内部模块(参见图3)
Java class 内部模块说明
相应之Reflection API,多半为Class methods。
返回值类型(return type)

(1) package
class隶属哪个package
getPackage()
Package

(2) import
class导入哪些classes
无直接对应之API。

解决办法见图5-2。
 

(3) modifier
class(或methods, fields)的属性


int getModifiers()

Modifier.toString(int)

Modifier.isInterface(int)
int

String

bool

(4) class name or interface name
class/interface
名称getName()
String

(5) type parameters
参数化类型的名称
getTypeParameters()
TypeVariable <Class>[]

(6) base class
base class(只可能一个)
getSuperClass()
Class

(7) implemented interfaces
实现有哪些interfaces
getInterfaces()
Class[]



(8) inner classes
内部classes
getDeclaredClasses()
Class[]

(8') outer class
如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。
getDeclaringClass()
Class

(9) constructors
构造函数getDeclaredConstructors()
不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
Constructor[]

(10) methods
操作函数getDeclaredMethods()
不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
Method[]

(11) fields
字段(成员变量)
getDeclaredFields()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
Field[]



图4:Java class大卸八块后(如图3),每一块所对应的Reflection API。本表并非

Reflection APIs 的全部。

相关推荐

    候捷谈Java反射机制

    ### 候捷谈Java反射机制 #### Java反射机制概览 Java反射机制是一种强大的运行时功能,使得Java能够在程序执行过程中动态地获取类的信息并操纵类的对象。这一特性极大地扩展了Java语言的能力,使其更加灵活多变。...

    java反射机制.zip

    java反射机制java反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制...

    java反射机制源码

    java反射机制源码java反射机制源码java反射机制源码

    Java反射机制的实现_Reflection

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...

    java 反射机制详解

    Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...

    java 反射机制例子

    ### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至修改自身的状态和行为。这种能力一经提出,迅速成为了计算机科学领域的研究...

    JAVA反射机制的入门代码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...

    java反射机制.md

    深入了解java反射机制的原理,通过反射机制可以破坏单例模式,如何防止通过反射机制拿到单例模式的构造器呢?用枚举类可破

    java反射机制讲解

    Java反射机制是Java语言提供的一种强大的能力,它允许我们在运行时检查类的信息并动态地创建和操作对象。这种机制使得程序具有更高的灵活性和扩展性,尤其是在框架开发中有着广泛的应用。 首先,我们要理解反射的...

    java反射机制原理和反射机制总结

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段以及方法等对象。这一机制的核心在于`java.lang.Class`类和相关的API,它们提供了对类元数据的访问,使得我们能够在运行时...

    java反射机制应用

    ### Java反射机制应用详解 #### 一、Java反射机制简介 Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建...

    利用java反射机制的建议计算器源码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的动态性和灵活性。在这个“利用java反射机制的建议计算器源码”中...

    java反射机制详解

    ### Java反射机制详解 #### 一、反射机制是什么 反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以...

    Java反射机制

    ### Java反射机制详解 #### 一、什么是Java的反射机制 Java反射机制是Java语言的一种重要特性,使得Java成为了一种动态性很强的语言。通过反射,可以在程序运行时获取类的信息,包括类名、父类、接口、字段、方法...

    Reflection_in_Java.zip_in_java 反射_java 反射机制_java反射_反射机制

    Java反射机制是Java编程语言中一个强大的特性,它允许运行时的程序动态地获取类的信息并操作类的对象。在Java中,反射主要涉及到`java.lang.Class`类、`java.lang.reflect`包下的类如`Constructor`、`Method`和`...

    java反射机制文档及代码

    Java反射机制是Java编程语言中一个强大的特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用方法以及...

    java反射机制PPT

    Java反射机制是Java编程语言中一项强大的工具,它允许程序在运行时检查和操作类、接口、对象等的内部信息。反射机制的核心在于能够在运行时动态地获取类的信息,并且可以动态调用对象的方法,创建对象,甚至修改对象...

    Java反射机制总结(实例分析)

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。通过反射,开发者可以在程序执行时发现并访问类的字段(fields)、方法(methods)以及构造器(constructors),...

    java 反射机制

    ### Java反射机制深入理解 #### 一、反射机制概述 Java反射机制是一种强大的工具,它允许程序在运行时检查和操作任何类、方法、构造函数和字段等元素。这种能力对于构建灵活的应用程序和框架非常有用,特别是那些...

Global site tag (gtag.js) - Google Analytics