反射,很容易让人与RTTI混淆起来。虽然二者都是获取类型信息的机制,但是二者是存在本质区别的。RTTI(Run-Time Type Information,运行时类型信息)是在编译时获取.class文件,而反射机制在编译阶段是获取不到.class文件的,只有在运行时才能去得到.class文件(当然也有可能找不到)。 |
看吧,仅仅是检查一下而已,简单吧。说它神奇,是因为反射可以让我们获取进行中的类的基本信息,这在C和C++里是不可想象的,而且反射也可以实现RMI(Remote Method Invoke,远程方法调用),我们可以呆在北京调用纽约的类创建和运用对象,想想就觉得神奇额,世界因为我们而变小,不愧是技术宅拯救全世界。我给反射下的定义是:反射,就是获取运行中的程序中一个未知类的基本的信息并对这些基本信息进行操作的机制。
反射怎么用?
那么,既然反射这么有用,要怎么用呢?
RTTI中得到类型信息有两种方法:Class.forName()和使用类字面常量。在反射机制里,考虑到我们在编译时不知道该类是否存在,因此类字面 常量的使用在反射里就无从说起了,我们在反射里使用的是Class.forName()方法(而在RTTI中,使用类字面常量效果更好),你会不会在想: 如果找不到这个类,会不会在编译时抛出ClassNotFoundException呢?答案是No(???) 。因为forName方法在编译时的结果是不可知的。具体的使用,我们将通过以下几个示例介绍:
// 父类 class Father{ String fName; public int a; public Father(){} public Father(String fName){ this.fName = fName; } // end constructor void fFun1(){System.out.println("Father.fFun1()");} void fFun2(String str){System.out.println("Father.fFun2()" + str);} public int fFun3(){System.out.println("Father.fFun3()");return 0;} } // end class Father // 子类 class Son extends Father{ String sStr; public Son(String sStr){this.sStr = sStr;} public void sFun1(){System.out.println("Son.sFun1()");} public void sFun2(int i){System.out.println("Son.sFun2()");} void sFun3(){System.out.println("Son.sFun3()");} } // end class Son
以上就是两个测试类的声明。由于反射的概念是靠Class类和 java.lang.reflect类库支撑起来的。因此我们要得到类的信息,就需要借助Method、Field以及Constructor等类。首 先,我们需要先得到一个Class对象(我们先假设我们不知道这个类里面有什么方法和属性,甚至不知道有木有这个.class文件):
Class c = Class.forName("com.tuyage.typeInfo.Son");
forName方法的参数是Son类的全限定名。接下来,我们先试图得到Son对象的构造器:
Constructor[] cons1 = c.getConstructors(); Constructor[] cons2 = c.getDeclaredConstructors(); System.out.println("#c.getConstructors()"); for(Constructor con: cons1){ System.out.println(con.toString()); } // end for System.out.println("#c.getDeclaredConstructors()"); for(Constructor con : cons2){ System.out.println(con.toString()); } // end for
可以看到,在这里,我们有两个取得构造器的方法:getConstructors()和getDeclaredConstructors()。等会也会看到Method和Field也有两种方法,下面就是这段代码运行的结果:
#c.getConstructors()
public com.tuyage.typeInfo.Son(java.lang.String)
#c.getDeclaredConstructors()
public com.tuyage.typeInfo.Son(java.lang.String)
两个结果是一样的,其实是有区别的,getConstructors()方法返回的是当前类的所有public的构造器,而getDeclaredConstructors()方法返回的是当前类的所有构造器。此处表现不明显,大家可以自己动手尝试。
接着看Method的获取:
Method[] meth1 = c.getMethods(); Method[] meth2 = c.getDeclaredMethods(); System.out.println("#c.getMethods()"); for(Method m: meth1){ System.out.println(m.toString()); } // end for System.out.println("#c.getDeclaredMethods()"); for(Method m : meth2){ System.out.println(m.toString()); } // end for
看看运行的结果:
#c.getMethods()
public void com.tuyage.typeInfo.Son.sFun1()
public void com.tuyage.typeInfo.Son.sFun2(int)
public int com.tuyage.typeInfo.Father.fFun3()
public final native java.lang.Class java.lang.Object.getClass()
public native int java.lang.Object.hashCode()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
#c.getDeclaredMethods()
public void com.tuyage.typeInfo.Son.sFun1()
public void com.tuyage.typeInfo.Son.sFun2(int)
void com.tuyage.typeInfo.Son.sFun3()
看到没,有很多方法名字冒出来了,而且还有很多我们很熟悉的,比如toString()、notify()等等,它们都是Object类的方法,因为,getMethods()方法得到的是该类及其父类的所有public方法,Object作为万物之父,它的方法出现在这里也就不足为奇了。大家还可以看到void com.tuyage.typeInfo.Son.sFun3()方法只出现在了getDeclaredMethods()方法里,因为这个方法是用来得到当前类所有方法的。
接下来,轮到Field出场了,当然是大同小异了,请看代码:
Field[] field1 = c.getFields(); Field[] field2 = c.getDeclaredFields(); System.out.println("#c.getFields()"); for(Field f: field1){ System.out.println(f.toString()); } // end for System.out.println("#c.getDeclaredFields()"); for(Field f : field2){ System.out.println(f.toString()); } // end for
运行结果如下:
#c.getFields()
public int com.tuyage.typeInfo.Father.a
#c.getDeclaredFields()
java.lang.String com.tuyage.typeInfo.Son.sStr
这个与Method的测试结果又有出入,使用getFields()方法时,并没有出现本类的field,而是父类的public属性,而getDeclaredFields()方法还是一样返回本类的所有属性(此处不明显,大家可以加几个属性试试)。
当然,建议大家一般使用getDeclaredXXXXX()方法。
小贴士:
main方法也可以被继承,因此也会在子类getMethods()方法的结果中也会出现(前提是父类有main方法,但是一般没有人这么做);
获得恰当的Class对象的引用是反射和RTTI的前提和基石;
Class对象仅在需要的时候才加载;
java.lang.reflect类库中的类的对象是由JVM在运行时创建的。
引自:http://www.java3z.com/cwbwebhome/article/article8/83590.html?id=4746
相关推荐
Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射机制提供了强大的能力,包括在运行时检查类的结构、创建对象实例、调用方法以及访问和修改字段值。...
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建对象、获取类...
Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...
在本文中,我们将深入探讨如何使用Java反射来获取并执行某个特定的方法。 首先,我们需要了解Java反射的基本概念。`java.lang.Class`类是反射的核心,它代表了Java中的每一个类。我们可以通过以下方式获取到一个...
### Java反射性能测试分析 #### 引言 Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的...
### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...
Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。在Java中,反射通常通过`java.lang.Class`类和相关的API来实现。本实例将...
### Java反射机制详解 #### 一、概述 Java反射机制是一种强大的编程技术,它允许运行时检查类的信息并操作对象的内部结构。本篇将基于Sun公司的官方文档《Java™ Core Reflection API and Specification》(1997年...
### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...
### Java反射机制详解 #### 一、什么是Java反射? Java反射是Java编程语言的一个特性,它允许运行时检查和操作程序结构(类、字段、方法等)。反射的主要用途包括但不限于:动态实例化对象、访问私有成员、调用...
Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...
Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有高度的灵活性,尤其在处理框架、插件系统以及元数据驱动...
### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至修改自身的状态和行为。这种能力一经提出,迅速成为了计算机科学领域的研究...
### Java反射机制与NoSuchMethodException详解 在Java编程中,反射是一种强大的机制,允许程序在运行时检查和修改自身结构和行为。然而,当开发者尝试使用反射调用一个不存在的方法时,便会遇到`java.lang....
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建动态代理等。...
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在给定的“利用java反射将json字符串转成对象”的主题中,我们将深入探讨如何借助反射机制将JSON...
### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的...
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...