`
lucky520
  • 浏览: 35783 次
  • 性别: 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反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射...以上内容不仅解释了Java反射机制的相关知识点,还通过示例代码进行了实践演示,希望能够帮助你在Java面试中更好地理解和运用这一重要特性。

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

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

    java反射机制+代码示例

    Java反射机制是Java编程语言中...通过实际的代码示例,学习和理解Java反射机制将变得更加直观和深入。在实际开发中,反射常用于框架、插件系统、序列化/反序列化、测试等方面,但也需要谨慎使用,避免过度依赖和滥用。

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    Java反射机制Demo

    ### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都...以上是关于Java反射机制的基本概念、用法和示例解析,希望能帮助你更好地理解和应用这一重要的Java特性。

    反射实例-JAVA反射机制

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

    java 反射机制详解

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

    java 反射机制例子

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

    Java反射机制学习(二)

    在"Java反射机制学习(二)"这篇博文中,作者可能详细解释了以上这些概念,并通过`BaseTest.java`和`Student.java`这两个示例文件进行了实例演示。`BaseTest.java`可能包含了一组基础的反射操作,而`Student.java`...

    java reflection反射机制示例

    Java反射机制是Java编程语言中的一个强大工具,它允许运行时动态访问类的信息,包括类名、属性、方法以及构造器等。通过反射,我们可以在程序执行过程中创建和操作任何类的对象,即使在编译时未知该类的具体信息。...

    Java 反射机制 代码的实例

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

    Java反射机制课件ppt

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

    java反射机制应用

    Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建对象,调用方法等。这为Java程序带来了极大的灵活性和扩展性...

    Java反射性能测试分析

    - [Oracle官方文档](https://docs.oracle.com/javase/tutorial/reflect/):提供关于Java反射机制的详细解释和示例。 - [Effective Java](https://www.amazon.com/Effective-Java-3rd-Edition/dp/0134685997):由...

    JAVA反射机制的简单理解

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

    java反射机制详解

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

    java反射机制文档及代码

    Java反射机制是Java编程语言中一个...通过阅读"1139760298222java.pdf"这份文档,你可以更深入地理解Java反射机制,并结合实际示例学习如何在项目中有效利用这一特性。记得在实际操作中结合代码实践,以巩固理论知识。

    JAVA反射机制动态调用 计算器对象的加法,减法函数;JAVA反射机制修改一个学生对象 的私有数据成员

    Java反射机制是Java语言提供的一种强大功能,它允许我们在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个机制在处理不确定类型或者需要灵活操作类的场景中非常有用。在这个...

    反射实例-JAVA反射机制.doc

    Java 反射机制详解 Java 反射机制是 Java 语言提供的一种强大的工具,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并进行操作。这种能力使得 Java 应用程序更加灵活,能够在运行时发现和修改自身...

Global site tag (gtag.js) - Google Analytics