zoukankan      html  css  js  c++  java
  • java 反射机制01

     

    java反射机制01

    1 反射机制

    • 反射的概念是由Smith 在1982年首次提出的,主要是指程序可以访问、检测和修改它本 身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性 的研究。它首先被程序语言的设计领域所采用,并在Lisp 和面向对象方面取得了成绩。 其中LEAD/LEAD++ 、OpenC++ 、MetaXa 和OpenJava 等就是基于反射机制的语言。
    • 有时候我们说某个语言的动态性,会用使用一些术语,如动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等,然而"动态" 一词其实没有绝对而普遍的严格定义,有时候甚至像面向对象当初被导入到编程领域一 样,一人一把号,各吹各的调。
    • 一般而言,开发者群说到动态语言,大致认同的一个定义是:"程序运行时,允许改变程 序结构或变量类型,这种语言称为动态语言",从这个观点看,perl,python,ruby是动 态语言,c++、java、c#不是动态语言。虽然java在这样的定义下不是动态语言,但他却 有一个非常突出的动态相关机制:reflection,这个词的意思是"反射、映象、倒影", 用在java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes, 换句话说,java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包 括methods定义),并生成其对象,或对其fields(变量)设值,调用其methods(方法),这 种"看透class"的能力(the ability of the program to examine itself),被称为 introspection(内省、内观、反省),reflection和introspection是常被并称的两个术 语。

    2 反射成员

    Java 的反射机制是通过反射API 来实现的,它允许程序在运行过程中取得任何一个已知名 称的类的内部信息.反射API位于java.lang.reflect 包中, Constructor,Field,Method这 三个类都是JVM在程序运行时创建的,用来表示加载类中相应的成员,这三个类都实现了 java.lang.reflect.Member,下表列出了反射机制涉及的主要类:

     
    类名描述
    java.lang.Class 是反射机制的基础,一切关于反射的故事,都从Class开始
    java.lang.ClassLoader 类加载器是负责加载类的对象
    java.lang.reflect.Constructor 用来描述一个类的构造方法
    java.lang.reflect.Field 用来描述一个类的成员变量
    java.lang.reflect.Method 用来描述一个类的方法
    java.lang.reflect.Modifer 用来描述类内各元素的修饰符
    java.lang.reflect.Array Array 类提供了动态创建和访问Java数组的方法

    2.1 java.lang.Class

    要使用反射,首先要得到Class对象,Class十分特殊,它和一般classes一样继承自 Object,其实体用以表达java执行期间的classes和interfaces,也用来表达 enumarrayprimitive java types(boolean,byte,short,int,long,double)以及关键字 void,当一个class被载入,或当载入器被(class loader)的defineClass()被JVM呼 叫,JVM便自动产一个Class object。如果想藉由"修改java程序源码"来观察Class object的实际生成机制(例如在Class的construct内添加一个println()),不能够!因为 Class并没有public construct(下面的Class源码)。

    public final
        class Class<T> implements java.io.Serializable, 
                java.lang.reflect.GenericDeclaration, 
                java.lang.reflect.Type,
                java.lang.reflect.AnnotatedElement {
        /*
         * Constructor. Only the Java Virtual Machine creates Class
         * objects.
         */
        private Class() {}
    ...
    

    Class是Reflection故事起源,针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个reflection APIs,这些下表列出了几种得到 Class对象的方法

     
    Class对象诞生方式代码示例
    用getClass(),每个对象都有这个方法 String str = "abc";
      Class clazz = str.getClass();
    用Class.forName(className),这是静态方法 Class clazz1 = Class.forName("java.lang.String");
      Class clazz2 = Class.forName("java.io.File");
    通过类的静态变量class Class clazz1 = String.class;
      Class clazz2 = File.class;
    用primitive wrapper classes的TYPE 语法 Class clazz1 = Double.TYPE;
      Class clazz2 = Void.TYPE;
      Class clazz3 = int.TYPE;

    2.2 Constructor

    通过Class调用newInatance方法可以创建类的实例,但只能调用类默认构造函数,即无 参数的构造函数,如果要调用有参数的构造函数,就需要获取类构造方法的 Constructor对象

     
    获取Constructor描述
    Constructor[] getDeclaredConstructors() 返回已加载类声明的所有构造方法的Constructor数组
    Constructor getDeclaredConstructor(Class[] paramTypes) 返回指定的,已加载类声明的构造方法的Constructor对象,
      paramTypes指定了参数类型
    Constructor[] getConstructors() 返回已加载类声明的所有public构造方法的Constructor数组
    Constructor getConstructor(Class[] paramTypes) 返回指定的,已加载类声明的public构造方法的Constuctor对象,
      paramTypes指定了参数类型

    2.3 Field

    通过Field对象可以获取类成员变量

     
    获取Field描述
    Field[] getDeclaredFields() 返回已加载类声明的所有成员变量的Field对象数组,不包括从父类继承的变量
    Field getDeclaredField(String name) 返回已加载类声明的成员变量的Filed对象,不包从父类继承的变量,
      参数name指定成员变量的名称
    Field[] getFields() 返回已加载类声明的所有public成员变量的Field对象数组,包括从父类继承的变量
    Field getField(String name) 返回已加载类声明的public成员变量的Field对象,包括从父类继承的变量,
      参数name指定成员变量的名称

    2.4 Method

    通过Method对象可以获取类方法

     
    获取Method描述
    Method[] getDeclaredMethods() 返回已加载类声明的所有方法的Method对象数组,不包括从父类继承的方法
    Method getDeclaredMethod(String name,Class[] types) 返回已加载类声明的Method对象,不包括从父类继承的方法,
      参数name指定方法的名称,参数paramTypes指定方法参数类型
    Method[] getMethods() 返回己加载类声明的public方法的Method对象数组,包括从父类继承的方法
    Method getMethod(String name,Class[] types) 返回己加载类声明的public方法的Method对象,包括从父类继承的方法,
      参数name指定方法的名称,参数paramTypes指定方法参数类型

    3 待续:实际的例子

     

    Date: 2013-08-09 17:45:54

    Author: machine.of.awareness@gmail.com

    Org version 7.8.06 with Emacs version 23

    Validate XHTML 1.0
  • 相关阅读:
    [LeetCode] Range Sum Query
    [LeetCode] Longest Increasing Subsequence
    [LeetCode] Bulls and Cows
    [LeetCode] Serialize and Deserialize Binary Tree
    [LeetCode] Find Median from Data Stream
    [LeetCode] Convert Sorted List to Binary Search Tree
    [LeetCode] Nim Game
    [LeetCode] Word Pattern
    安装配置说明与注意
    java.lang.OutOfMemoryError: PermGen space及其解决方法
  • 原文地址:https://www.cnblogs.com/machine/p/3227051.html
Copyright © 2011-2022 走看看