`
lucky520
  • 浏览: 35469 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
社区版块
存档分类
最新评论

java反射机制示例与分析

阅读更多
      Java反射机制通过JVM运行时动态获取类信息以及动态调用对象的方法。其实反射并不像我们想象的那么神秘,复杂。它通过java.lang.Class以及java.lang.reflect包的API实现的反射功能。我们在Spring AOP,JDBC数据库加载驱动都有用到反射机制。下面通过几段代码示例看看reflection究竟是如何工作的。
package com.me.reflection;
import java.lang.reflect.*;

public class DumpMethods {
    public static void main(String args[]) {
        try {
            Class c = Class.forName("java.lang.String"]);//1
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
                System.out.println(m[i].toString());
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}

大家对代码1处蛮眼熟吧,没错,在JDBC数据库加载驱动中用到了。这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Method是用来描述某个类中单个方法的一个类。
总结:获得指定类的方式有(1)Class.forName("") (2).class 如int.class (3)包装类.TYPE 如:Integer.TYPE
package com.me.reflection;

import java.lang.reflect.*;

public class MethodDemo {
    private int f1(Object p, int x) throws NullPointerException {
        if (p == null)
            throw new NullPointerException();
        return x;
    }

    public static void main(String args[]) {
        try {
            Class cls = Class.forName("com.me.reflection.MethodDemo");
//获得指定类的所有方法。通过getMethods()返回指定类所有公共方法
            Method methlist[] = cls.getDeclaredMethods();
            for (int i = 0; i < methlist.length; i++) {
                Method m = methlist[i];
                System.out.println("name = " + m.getName());
                System.out.println("decl class = " + m.getDeclaringClass());
//获得每个方法的参数类型类表数组
                Class pvec[] = m.getParameterTypes();
                for (int j = 0; j < pvec.length; j++)
                    System.out.println("param #" + j + " " + pvec[j]);
           }
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}

这个程序首先取得 MethodDemo类的描述,然后调用 getDeclaredMethods 来获取一系列的 Method 对象,它们分别描述了定义在类中的每一个方法,包括 public、protected package和private方法等。如果你在程序中使用getMethods来代替getDeclaredMethods,你还能获得继承来的各个方法的信息。

package com.me.reflection;

import java.lang.reflect.*;

public class ConstructorDemo {
    public ConstructorDemo () {
    }

    protected ConstructorDemo (int i, double d) {
    }

    public static void main(String args[]) {
        try {
            Class cls = Class.forName("com.me.reflection.ConstructorDemo");
//获得指定类的所有构造方法。通过getConstructors()返回指定类所有公共构造方法
            Constructor ctorlist[] = cls.getDeclaredConstructors();
            for (int i = 0; i < ctorlist.length; i++) {
                Constructor ct = ctorlist[i];
                System.out.println("name = " + ct.getName());
                System.out.println("decl class = " + ct.getDeclaringClass());
//获得每种构造方法的参数类型类表数组
                Class pvec[] = ct.getParameterTypes();
                for (int j = 0; j < pvec.length; j++)
                    System.out.println("param #" + j + " " + pvec[j]);
           }
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}

获取类构造器的用法与上述获取方法的用法类似。
package com.me.reflection;
import java.lang.reflect.*;

public class FieldDemo{
    private double d;
    public static final int i = 37;
    String s = "testing";

    public static void main(String args[]) {
        try {
            Class cls = Class.forName("com.me.reflection.FieldDemo");
            Field fieldlist[] = cls.getDeclaredFields();
            for (int i = 0; i < fieldlist.length; i++) {
                Field fld = fieldlist[i];
                System.out.println("name = " + fld.getName());
                System.out.println("decl class = " + fld.getDeclaringClass());
                System.out.println("type = " + fld.getType());
                int mod = fld.getModifiers();
                System.out.println("modifiers = " + Modifier.toString(mod));
                System.out.println("-----");
            }
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}


这个例子和前面那个例子非常相似。例中使用了一个新东西 Modifier,它也是一个 reflection 类,用来描述字段成员的修饰语,如“private int”。这些修饰语自身由整数描述,而且使用 Modifier.toString 来返回以“官方”顺序排列的字符串描述 (如“static”在“final”之前)。

以上显示了通过reflection获得类信息的这种用法。那么如何动态创建类对象,调用方法呢
package com.me.reflection;

import java.lang.reflect.*;

public class ReflectionApp {
    public ReflectionApp(){}

    public ReflectionApp(int a,int b){
       System.out.println("a = " + a + " b = " + b);
    }
    
    public int add(int a, int b) {
        return a + b;
    }
    public static void main(String args[]) {
        try {
            Class cls = Class.forName("com.me.reflection.ReflectionApp");
   Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
//创建类对象 如果指定类只有默认构造方法,我们可通过cls.newInstance()直接生成类对象,只有Class和Constructor这两个类可以直接生成类对象         
            Constructor ct = cls.getConstructor(partypes);
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
[color=red]//注意:Class#getConstructor和Constructor#newInstance方法参数类型是一致的[/color]
            ReflectionApp ra = (ReflectionApp)ct.newInstance(arglist);
//获得指定类指定方法
            Method meth = cls.getMethod("add", partypes);
//动态调用类方法:通过invoke(指定类对象,方法参数类型列表)方法           
            Object retobj = meth.invoke(ra, arglist);
            Integer retval = (Integer) retobj;
            System.out.println(retval.intValue());
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}

很多同学认为创建一个对象调用一下方法怎么写这么麻烦,但是使用这种方法可以在程序运行时动态地创建对象,动态调用方法,而不是在编译的时候创建对象,这一点非常有价值。大家可以参照Java API研究下如何改变属性值等其他功能。动态创建数组将在以后的文章写到。
4
3
分享到:
评论
5 楼 278506470 2008-10-21  
lucky520 写道

wiely 写道
8) 写得太肤浅啦,而且也不一定是你自己写的吧 怎么不是我写的呢?我也觉得还不够深入,我也只学到这些,你有什么深入的理解,写出来大家探讨一下吧!

我觉得写的很好啊,这位仁兄真是没有眼光啊,这里写的反射机制层层深入,逐步分析,是一份很不错的学习文档。
4 楼 wiely 2008-10-21  
而且也不一定是你自己写的吧
lucky520 写道

wiely 写道
8) 写得太肤浅啦,而且也不一定是你自己写的吧 怎么不是我写的呢?我也觉得还不够深入,我也只学到这些,你有什么深入的理解,写出来大家探讨一下吧!

还没有。谢谢。
3 楼 lucky520 2008-10-21  
wiely 写道

8) 写得太肤浅啦,而且也不一定是你自己写的吧

怎么不是我写的呢?我也觉得还不够深入,我也只学到这些,你有什么深入的理解,写出来大家探讨一下吧!
2 楼 wiely 2008-10-21  
写得太肤浅啦,而且也不一定是你自己写的吧
1 楼 278506470 2008-10-20  
你的文章都还是比较不错的了,最近比较忙吧!

相关推荐

    java反射机制+代码示例

    java反射机制+代码示例.rar 看一遍我就明白这是怎么一回事了~~

    java reflection反射机制示例

    讲述java 反射机制的典型示例,通过学习应该能很好的掌握

    Java反射机制学习总结

    Java反射机制学习总结,附带程序示例。

    java反射示例代码

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

    java反射机制示例

    主要介绍了java反射机制示例,需要的朋友可以参考下

    java中的反射机制的示例

    java中的反射机制的示例,反射在java的开发过程中是经常用到的,会使你的代码更灵活,更优秀.

    java反射机制示例详解

    反射就是加载类,并解剖出类的各个组成部分,下面介绍了java反射机制示例,大家参考使用吧

    java反射机制介绍及使用

    1、本文详细描述了java反射机制的作用及使用方法。 2、通过详细示例,让读者更直观地阅读,更清晰的理解。 3、示例代码可直接复制,编译后可直接运行。 4、根据示例以及运行结果,让读者加强记忆及理解。

    JAVA反射机制实例教程

    主要介绍了JAVA反射机制,包括了Java反射机制的各种应用技巧,非常具有实用价值,需要的朋友可以参考下

    java反射机制详解

    java反射API的详细说明及调用的示例说明等

    java反射机制实战示例分享

    主要介绍了java反射机制实战示例,需要的朋友可以参考下

    【Java】反射机制介绍与Class类的基本能使用(工厂模式)

    Java反射机制与Class类1.Java反射机制1.1 反射机制是什么1.2 反射的应用场合1.3 反射的常用类1.4 反射使用步骤2. Class类2.1 常用方法和示例2.2 获取Class对象的 3 种方法2.3 反射创建对象的 2 种方法3. 工厂设计...

    Java反射_Spring IOC

    《Java语言的反射机制.pdf》资料书,示例源代码JAVA+Spring,初学java反射者可以看看

    Java开发技术大全(500个源代码).

    代码范例列表 第1章 ... useArray2.java 用反射机制使用数组示例2 第10章 示例描述:本章学习泛型。 demoBounds.java 演示有界类型 demoForceChange.java 演示强制类型转换 demoGeneric.java ...

    JAVA反射 代理 PPT

    介绍JAVA反射机制,及代理模式,展示相应示例.

    反射机制 上课示例

    获得类名 判断是接口还是类 获得修饰符 final public 获得父类 获得接口 获得字段 (某个,所有) 获得字段类型 获得私有字段 获得构造 (某个,所有) 获得构造参数 获得方法 获得返回类型 ...有非常详细的注释

    JAVA Reflection(反射机制)

     尽管在这样得定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关的机制:反射机制 (Reflection)。  什么是反射?  反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改...

    Java的动态代理、反射机制和数据库连接池技术

    里面有很多我做项目时候总结的ppt文档和示例。 包括很多一些Java机制用法和一下常用技术 希望大家喜欢

    Java基于反射机制实现全部注解获取的方法示例

    主要介绍了Java基于反射机制实现全部注解获取的方法,结合实例形式分析了java反射机制获取注解的具体实现方法与操作注意事项,需要的朋友可以参考下

    使用Java反射实现一个简单的日志记录器.txt

    这段代码实现了一个简单的日志记录器LoggerUtil,其中使用了Java的反射机制。在类的构造方法中,创建了一个...这个简单的示例代码展示了如何使用Java反射来实现一个日志记录器,方便了对程序运行时信息的记录和管理。

Global site tag (gtag.js) - Google Analytics