`
wanglihu
  • 浏览: 918313 次
  • 性别: Icon_minigender_1
  • 来自: 黑龙江
社区版块
存档分类

java反射机制

    博客分类:
  • java
阅读更多

    Java提供的反射机制允许你在运行时动态加载类、查看类信息、生成对象或操作生成的对象。在整合式开发环境中所提供的方法提示或是泪查看工具,还有象JSP中的JavaBean自动收集请求信息也使用到反射,而一些软件开发框架(Framework)也常见到反射机制的使用,以达到动态加载使用者自定义类的目的。反射其实就是程序能够自检查自身信息。就像程序会照镜子反光看自己。
在程序中可以检查某个类中的方法属性等信息,并且能够动态调用。 这样可以写出很灵活的程序。 比如要把一个对象中的数据copy到另外一个对象中,规则是属性名相同就copy, 就可以用反射来做,不需要指定每个属性的名字,只要动态从类中取得信息,
再判断属性名是否相同即可。当然应用还有很多。 反射可以结合Java的字节码,使用ASM和cglib等库,还能动态生成类。
hibernate的延迟载入,spring的AOP都是这么实现的 。反射给Java带来了一些动态性。不过虽然很好,但毕竟还是有一定局限性的。另外ASM,cglib使用还是不放便。因此一些纯动态语言现在是一个重要发展趋势,比如ruby,python等,程序很容易动态生成。

    那到底什么叫反射机制呢?

   1. java程序在运行时可以获得任何一个类的字节码信息,包括类的修饰符(public,static等),基类(超类,父类),实现的接口,字段和方法等信息。
   2. java程序在运行时可以根据字节码信息来创建该类的实例对象,改变对象的字段内容和调用对象方法.
我们把上面这种机制就叫反射技术。因为Java在真正需要使用一个类的时候才会加以加载,而不是在程序启动时就加载所有的类。大多数使用者都只使用到应用程序的部分资源,在需要某些功能时才加载某些资源,可以让系统的资源运用更有效率(Java本身就是为了资源有限的小型设备而设计的,这样的考虑是必然的)。
   
Java的反射机制是通过反射API来实现的,它允许程序在运行过程中取得任何一个已知名称的类的内部信息.反射API位于java.lang.reflect包中.主要包括以下几类:
         1).Constructor类:用来描述一个类的构造方法
        2).Field类:用来描述一个类的成员变量
        3).Method类:用来描述一个类的方法.
        4).Modifer类:用来描述类内各元素的修饰符
        5).Array:用来对数组进行操作.
获取类的构造方法的Constructor对象(数组)
    Constructor[] getDeclaredConstructors();返回已加载类声明的所有的构造方法的Constructor对象数组.
   Constructor getDeclaredConstructor(Class[] paramTypes);返回已加载类声明的指定构造方法的Constructor对象,paramTypes指定了参数类型.
   Constructor[] getConstructors();返回已加载类声明的所有的public类型的构造方法的Constructor对象数组.
    Constructor getConstructor(Class[] paramTypes);返回已加载类声明的指定的public类型的构造方法的Constructor对象,paramTypes指定了参数类型.
如果某个类中没有定义构造方法,第一个和第三个方法返回的数组中只有一个元素,就是缺省的构造方法;如果某个类中只定义了有参数的构造函数,而没有定义缺省构造函数,第一个和第三个方法返回的数组中不包含缺省的构造方法.
例子:
package com.vincent.test;
import java.lang.reflect.*;
public class DumpMethods {
    
public static void main(String[] args) {
        
try {
            
if (args.length < 1) {
                 System.out.println(
"请输入完整的类名:");
                
return;
             }
             Class strClass
= Class.forName(args[0]);
            
//检索带有指定参数的构造方法
             Class[] strArgsClass = new Class[]{byte[].class, String.class};
             Constructor constructor
= strClass.getConstructor(strArgsClass);
             System.out.println(
"Constructor:" + constructor.toString());
            
//调用带有参数的构造方法创建实例对象object
            byte[] bytes = "IT年薪".getBytes();
             Object[] strArgs
= new Object[]{bytes, "GBK"};
             Object object
= constructor.newInstance(strArgs);
             System.out.println(
"Object" + object.toString());
         }
catch (Exception e) {
             e.printStackTrace();
         }
     }
}

 

Field[] getDeclaredFields():返回已加载类声明的所有成员变量的Field对象数组,不包括从父类继承的成员变量.

Field getDeclaredField(String name):返回已加载类声明的所有成员变量的Field对象,不包括从父类继承的成员变量,参数name指定成员变量的名称.

   Field[] getFields():返回已加载类声明的所有public型的成员变量的Field对象数组,包括从父类继承的成员变量
   Field getField(String name):返回已加载类声明的所有成员变量的Field对象,包括从父类继承的成员变量,参数name指定成员变量的名称.
例子:
package com.vincent.test
import java.lang.reflect.*;
public class ReflectTest {
        
private String name;
        
private String passwd;
        
public ReflectTest(String name,String passwd){
               
this.name=name;
               
this.passwd=passwd;
         }

        
public static void main(String[] args) {
             
try{
                   ReflectTest rt
=new ReflectTest("Vincent","spring");
                   fun(rt);
              }
catch(Exception e){
                      e.printStackTrace();
              }
        }
        
public static void fun(Object obj) throws Exception{
                Field[] fields
=obj.getClass().getDeclaredFields();
                System.out.println(
"修改之前的值:");
               
for(Field field:fields){
                     System.out.println(field.getName()
+"="+field.get(obj));
                   
if(field.getType().equals(java.lang.String.class)){
                         
//必须设置为true才可以修改成员变量
                          field.setAccessible(true);                              String org=(String)field.get(obj);
                          field.set(obj,org.replaceAll(
"g","a"));
                    }
          }
          System.out.println(
"修改之后的值:");
         
for(Field field:fields){
                 System.out.println(field.getName()
+"="+field.get(obj));
          }
       }
}

 

获取类的方法的Method对象(数组)
    Method[] getDeclaredMethods():返回已加载类声明的所有方法的Method对象数组,不包括从父类继承的方法.
    Method getDeclaredMethod(String name,Class[] paramTypes):返回已加载类声明的所有方法的Method对象,不包括从父类继承的方法,参数name指定方法的名称,参数paramTypes指定方法的参数类型.
   Method[] getMethods():返回已加载类声明的所有方法的Method对象数组,包括从父类继承的方法.
   Method getMethod(String name,Class[] paramTypes):返回已加载类声明的所有方法的Method对象,包括从父类继承的方法,参数name指定方法的名称,参数paramTypes指定方法的参数类型.
检索类的其他信息
   int   getModifiers():返回已加载类的修饰符的整形标识值.
   Package getPackage():返回已加载类的包名
   Class   getSuperclass():返回已加载类的父类的Class实例.
   Class []   getInterfaces():返回已加载类实现的接口的Class对象数组.
   boolean isInterface():返回已加载类是否是接口.
有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。
 
一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,答应改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
 
尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
 
Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、ConstrUCtor等等classes。
 
“Class”class
众所周知Java有个Object class,是所有Java classes的继续根源,其内声明了数个应该在所有Java class中被改写的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class object。
 
Class class十分非凡。它和一般classes一样继续自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及要害词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class object。假如您想借由“修改Java标准库源码”来观察Class object的实际生成时机(例如在Class的constructor内添加一个println()),不能够!因为Class并没有public constructor(见图1)。本文最后我会拨一小块篇幅顺带谈谈Java标准库源码的改动办法。
      Class是Reflection故事起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs。这些APIs将在稍后的探险活动中一一亮相。
 
public final class Class<T> implements java.io.Serializable,java.lang.reflect.GenericDeclaration,java.lang.reflect.Type,java.lang.reflect.AnnotatedElement {
  private Class() {}
  public String toString() {
   return ( isInterface() ? "interface " :
     (isPrimitive() ? "" : "class "))
  + getName();
 }
注重它的private empty ctor,意指不答应任何人经由编程方式产生Class object。是的,其object 只能由JVM 产生。
 
分享到:
评论

相关推荐

    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.lang.reflect包下,包括Class、Constructor、Method和...

    java 反射机制

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

    JAVA反射机制的简单理解

    Java反射机制是Java语言提供的一种强大工具,它允许在程序运行时动态地获取类的信息以及对类的对象进行操作。在Java中,静态编译时类型检查确保了代码的稳定性,但有时我们需要在运行时根据需求动态地创建对象、调用...

    Java 反射机制 代码的实例

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    java 反射机制详解

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

    Java反射机制学习(二)

    这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...

    java反射机制和动态代理的原理

    java反射机制和动态代理的原理,熟悉反射机制和动态代理

    Java反射机制 Java反射机制

    ### Java反射机制详解 #### 一、Java反射机制概述 Java反射机制是Java语言的一个重要特性,它允许程序在运行时获取类的信息并操作对象。Java反射机制的主要作用包括:获取类的所有属性和方法、构造动态实例、调用...

    Java反射机制课件ppt

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。这种机制使得Java具有高度的灵活性和动态性,可以在编译时未知类的情况下进行类的加载、实例化、方法调用等操作...

    java反射机制工具类

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息。这个特性使得Java具备了高度的灵活性,能够在运行时动态地发现和使用类的属性和方法,即使这些信息在编译时...

    java反射机制,很安逸.不要错过

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、字段和方法的信息,打破了通常编译时静态绑定的限制。通过反射,我们可以动态地创建对象,调用方法,访问和修改字段值,甚至...

    java面试题--反射机制

    ### Java反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射机制相关的题目。这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射...

    java反射机制核心代码

    java反射机制核心代码,小弟一直弄不明白,怎么通过反射来调用私有成员方法,看了这个后,你可以随心调用private方法,和属性,记得添加setAccessable(true),哦,要不还是不行,如:method.setAccessable(true);

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

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

Global site tag (gtag.js) - Google Analytics