`
ginger547
  • 浏览: 35069 次
  • 性别: Icon_minigender_1
  • 来自: CC
社区版块
存档分类
最新评论

Reflection-Java中的反射机制

阅读更多

Reflection-Java中的反射机制

Author:ginger547

Java looking at Java

   Java的一个很不寻常的能力,它允许一个程序检查自己
   你可以确定一个对象所属的类型
   你可以查看一个类的全部内容,它们的访问修饰符、父类、字段、构造函数、方法
   你可以查看一个接口的内容
   即使在编写代码的时候你不知道事物的名字你也可以做到:
   创建一个类的实例
   取得和设置一个实例的变量
   调用一个对象的一个方法
   创建和操作数组

   我猜它之所以被称为“反射”是因为它允许一个Java应用程序像“在镜子里”看到自己一样。

What is reflection for?

   在“平常”的程序中你可能用不到反射
   如果你是在使用应用程序来操作应用程序,那你就需要使用反射了。
   典型的应用:
   一个类型查看器
   一个调试程序
   一个GUI创建器
   一个IDE,比喻说BlueJ或Eclipse

IDE

   有需要的IDE本身就是用Java编写的—它们可以做什么?
   编译一个程序(简单—只是一个系统调用)
   编译后加载进你的系统
   弄清楚你都有些什么类,它们的构造函数和方法
   执行你的main方法
   替你创建对象,即使现在没有运行main方法
   为对象传递信息,并显示结果
   这些所有的功能,除了编译都是使用反射做到的

Class 类

   要发现一个具体的类的信息,首先要取得它的Class 对象
   如果你有一个 obj 对象,你可以通过下面的方式来取得它的class对象
Class c = obj.getClass();
   你可以通过一个class的实例c 取得它的父类
Class sup = c.getSuperclass();
   如果你已经知道一个类在编译时候的名字 (比喻说, Button) ,你可以通过下面这样的简单方法取得class对象
Class c = Button.class;
   如果你知道一个类在运行期的名字(比喻说,一个String类型变量str),你可以通过下面的方法取得类对象
Class c = Class.forName(str);

取得类的名字

   如果你已经有了一个class对象c,你可以通过下面的方法取得类的名字 c.getName()
   getName 取得类的全路径名字; 比喻说,
    Class c = Button.class;
    String s = c.getName();
    System.out.println(s);
会输出
    java.awt.Button
   类 Class 和它的方法都是在 java.lang中,所以不需要使用import使其可用。

取得所有的父类

   getSuperclass() 返回一个 Class 对象 (或者 null 如果你在 Object上使用的话,它是没有父类的 )

   下面的代码来自Sun的入门指南:

     static void printSuperclasses(Object o) {
     Class subclass = o.getClass();
     Class superclass = subclass.getSuperclass();
     while (superclass != null) {
     String className = superclass.getName();
     System.out.println(className);
     subclass = superclass;
     superclass = subclass.getSuperclass();
          }
}

取得类的修饰符I

   Class对象有一个实例方法 getModifiers() ,它返回一个int型的值

   为了“解释” int 型的结果,我们要用到Modifier类的一些方法,它们位于 java.lang.reflect, 所以:

    import java.lang.reflect.*;

   现在我们就可以做下面的事情了:

if (Modifier.isPublic(m)) {
    System.out.println("public");
}

取得类的修饰符II

   Modifier 包含下面的一些方法 (只列出部分):
   public static boolean isAbstract(int)
   public static boolean isFinal(int)
   public static boolean isInterface(int)
   public static boolean isPrivate(int)
   public static boolean isProtected(int)
   public static boolean isPublic(int)
   public static String toString(int)
   这会返回一个如下所示的字符串
"public final synchronized strictfp"

取得接口

   一个类可以实现0个或多个接口
   getInterfaces() 返回一个 Class 对象的数组
   这些是类实现的一些接口
   下面的代码来自Sun的入门指南:
   static void printInterfaceNames(Object o) {
    Class c = o.getClass();
    Class[ ] theInterfaces = c.getInterfaces();
    for (int i = 0; i < theInterfaces.length; i++) {
       String interfaceName = theInterfaces[i].getName();
       System.out.println(interfaceName);
    }
}
   注意:零长度数组在Java中是合法的

判断类和接口

   Class 类既能代表类也能代表接口
   要确定一个给定的 Class 对象 c 是否是一个是接口,可以使用 c.isInterface()
   要研究class对象的更多内容的话,你可以使用下面这些方法:
   getModifiers()
   getFields()    // "fields" == "instance variables"
   getConstructors()
   getMethods()
   isArray()

取得字段

   public Field[] getFields() throws SecurityException
   返回一个public的字段数组 (变量)
   数组的长度允许是0
   字段的组织顺序没有任何的规则
   本身定义的和通过继承的来的变量都被返回,但是不包含 static 变量
   public Field getField(String name)
    throws NoSuchFieldException, SecurityException
   返回指定名称的 public 字段
   如果没有直接的字段被发现,那父类或者接口被递归的查询

使用字段 I

   如果 f 是 Field 对象, 那么
   f.getName() 返回字段的简单的名字
   f.getType() 返回字段的类型 (Class)
   f.getModifiers() 返回字段的Modifier
   f.toString() 返回一个包含了访问修饰符,类型,和全路径字段名字的字符串
   例如: public  java.lang.String  Person.name
   f.getDeclaringClass() 返回定义字段的类的 Class 对象

使用字段 II

   obj 对象的字段的值可以使用下面的方式进行操作:
   boolean f.getBoolean(obj),
int f.getInt(obj),
double f.getDouble(obj),
等等,返回字段的值,假设它是那个类型或者可以扩展成那个型
   Object f.get(obj) 返回一个字段的值,假设它是一个对象
   void f.set(obj, value),
void f.setBoolean(obj, bool),
void f.setInt(obj, i),
void f.getDouble(obj, d),等等,设置一个字段的值

构造函数

   如果 c 是一个构造函数,那么
   c.getName() 返回构造函数的名字,与类的名字完全一致
   c.getDeclaringClass() 返回构造函数被声明的 Class 对象
   c.getModifiers() 返回构造函数的 Modifier
   c.getParameterTypes() 返回一个Class 对象数组, 以声明的顺序
   c.newInstance(Object[] initargs) 创建被返回一个c类的实例对象
   需要使用简单类型的地方会被自动的转换

方法

   public Method[] getMethods()
          throws SecurityException
   返回一个 Method 对象数组
   返回的是类或接口的 public 成员方法,同时也包含继承的来的方法
   返回的方法没有任何的顺序
   public Method getMethod(String name,
                                       Class[] parameterTypes)
throws NoSuchMethodException, SecurityException

Method 中的方法 I

   getDeclaringClass()
   返回一个Class 对象,它代表了这个Method 对象所被声明的类或接口
   getName()
   返回代表这个Method 对象的名字,以字符串的方式
   getModifiers()
   返回代表这个Method 对象的修饰符,以整型的方式
   getParameterTypes()
   返回这个Method 对象所需要的参数的 Class 对象数组,以声明的顺序出现

Method 中的方法 II

   getReturnType()
   返回代表这个Method 对象的返回值的一个 Class对象名字
   toString()
   返回一个代表这个Method 对象的字符串,通常情况下会很长
   public Object invoke(Object obj, Object[] args)
   在特定的对象上使用特定的参数,执行这个Method对象所代表的方法
   个别的参数会被自动转换来实现一些对基本数据类型的需要

数组 I

   可以采用下面的方法来判断一个obj 对象是不是一个数组
   Class c = obj.getClass();
   c.isArray()
   要取得这个数组的元素的类型可以使用,
   c.getComponentType()
   如果c不是一个数组的话会返回一个 null
   在java.lang.reflect 包中包含了一个 Array 类,它提供了一些 static 方法来操作数组

数组 II

   要创建一个数组,
    Array.newInstance(Class componentType, int size)
   返回一个新创建的数组Object对象,
   你可以把它造型成你想要的类型
   componentType 本身就可以是一个数组
   这会产生一个多维数组
   维数的最大限制一般在255
   Array.newInstance(Class componentType, int[] size)
   返回一个新创建的多维数组Object对象 (使用 size.length 维度)

数组 III

   得到数组元素的值
   Array.get(Object array, int index) 返回一个 Object
   Array.getBoolean(Object array, int index) 返回一个 boolean
   Array.getByte(Object array, int index) 返回一个 byte
   等等.
   往数组中保存值,
   Array.set(Object array, int index, Object value)
   Array.setBoolean(Object array, int index, boolean z)
   Array.setByte(Object array, int index, byte b)
   等等.

结束语

   很多方法都有自己的异常,我在这里没有描述
   要查看详情,你参照Java API
   反射在“平常”的程序中用不到,可是你真的需要它的时候却是不可替代的。
   一个相关的话题-类的加载器(class loaders)—Java把需要的类读进内存
   你可以编写你自己的加载器
   这是别的大多数语言不包含的一种功能

The End

分享到:
评论

相关推荐

    java面试题--反射机制

    `Class`类在Java反射机制中扮演着核心角色,它是所有Java类的运行时表示。`Class`对象可以由以下几种方式获取: 1. **通过类的`Class`属性获取**:如`String.class`。 2. **通过对象的`getClass()`方法获取**:如`...

    反射实例-JAVA反射机制

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

    reflection-of-java.rar_reflection of java

    总的来说,"reflection of java.pdf"文档将深入讲解Java反射机制的各个方面,包括基本用法、高级应用以及最佳实践,对理解Java反射机制及其在实际开发中的应用非常有帮助。通过学习这份资料,开发者能够更好地掌握...

    精华java-反射机制-reflection-完整例子-具体说明-工程实际(完整版).doc

    Java反射机制是Java语言提供的一种强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,甚至能够在运行时动态地创建和修改对象。本文将深入探讨反射机制的概念、用途、优缺点以及如何使用反射来获取类的...

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

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

    java-reflection-Xiangjie.rar_java 反射

    Java反射是Java编程语言中的一个强大工具,它允许程序在运行时检查类、接口、字段和方法的信息,并能动态地创建对象和调用方法。在深入理解Java反射之前,我们首先要明白什么是反射机制。反射机制是指在运行状态中,...

    JAVA 私塾笔记整理——反射机制(Reflection)

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

    javaReflection反射机制.ppt

    之前上课的时候老师总结的JavaReflection反射学习资料,内容简单易懂,浅显易懂,适合小白入手学习。。

    Java中的反射机制

    Java反射机制允许运行中的程序检查自身,并能直接操作程序的内部属性。这是其他许多编程语言(如Pascal、C或C++)不具备的能力。 **1.1 Reflection的工作机制** 为了展示反射如何工作,我们来看一个简单的例子: ...

    alheli-reflection-1.1.jar.zip

    《深入理解Java反射机制——以alheli-reflection-1.1.jar为例》 在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,甚至可以动态地创建对象并调用其方法...

    Java反射机制的实现_Reflection

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

    Java-Reflection-Tutorial.pdf

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、对象、接口、枚举、方法、构造器等元素。在Java中,反射机制的核心是`java.lang.Class`对象,它代表了Java运行时的类信息。通过反射...

    Java反射机制 Java反射机制

    Java反射机制在JDK 1.1版本中就已经引入,但在JDK 1.5之后得到了进一步增强和完善,增加了泛型支持等功能,使得反射更加安全和强大。 #### 三、Java反射机制的核心概念与应用 1. **核心概念** - **Class对象**:...

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

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

    java的反射机制及其实际应用

    ### Java的反射机制及其实际应用 #### 一、引言 ...总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,避免滥用造成不必要的性能损失或安全风险。

    Java Reflection (JAVA反射)

    ### Java反射机制详解 #### 一、Java反射机制概述 反射是Java编程语言的一个关键特性,它赋予了Java程序在运行时自我检查的能力,并能够直接操纵程序内部的属性。通过反射,开发者可以在运行时获取类的信息(如...

    Java Reflection (JAVA反射)详解

    以下是对Java反射机制的详细解释: 1. 获取类信息: 要使用反射,首先需要获取类的`java.lang.Class`对象。这可以通过以下几种方式实现: - `Class&lt;?&gt; c = Class.forName("全限定类名");`:根据类的全限定名(包...

Global site tag (gtag.js) - Google Analytics