反射 (Reflection) ,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
内省 (Introspector),是“看透class”的能力(内省、内观、反省)。
Java允许我们从多种管道为一个class生成对应的Class object。
Class object 诞生管道
|
示例
|
运用getClass()
注:每个class 都有此函数
|
String str = "abc";
Class c1 = str.getClass();
|
运用
Class.getSuperclass()2
|
Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
|
运用static method
Class.forName()
(最常被使用)
|
Class c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName ("[I");
|
运用
.class 语法
|
Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
|
运用
primitive wrapper classes
的TYPE 语法
|
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;
|
图1:Java 允许多种管道生成Class object。
以图2的java.util.LinkedList为例,将Java class的定义大卸八块,每一块分别对应图3所示的Reflection API。
package java.util; //(1)
import java.lang.*; //(2)
public class LinkedList<E> //(3)(4)(5)
extends AbstractSequentialList<E> //(6)
implements List<E>, Queue<E>,
Cloneable, java.io.Serializable //(7)
{
private static class Entry<E> { … }//(8)
public LinkedList() { … } //(9)
public LinkedList(Collection<? extends E> c) { … }
public E getFirst() { … } //(10)
public E getLast() { … }
private transient Entry<E> header = …; //(11)
private transient int size = 0;
}
图2:将一个Java class 大卸八块,每块相应于一个或一组Reflection APIs(图3)。
图2的各个Java class成份,分别对应于图3的Reflection API,其中出现的Package、Method、Constructor、Field等等classes,都定义于java.lang.reflect。本表并非Reflection APIs 的全部。
Java class 内部模块(参见图3)
|
Java class 内部模块说明
|
相应之Reflection API,多半为Class methods。
|
返回值类型(return type)
|
(1) package
|
class隶属哪个package
|
getPackage()
|
Package
|
(2) import
|
class导入哪些classes
|
无直接对应之API。
解决办法见图5-2。
|
|
(3) modifier
|
class(或methods, fields)的属性
|
int getModifiers()
Modifier.toString(int)
Modifier.isInterface(int)
|
int
String
bool
|
(4) class name or interface name
|
class/interface
|
名称getName()
|
String
|
(5) type parameters
|
参数化类型的名称
|
getTypeParameters()
|
TypeVariable <Class>[]
|
(6) base class
|
base class(只可能一个)
|
getSuperClass()
|
Class
|
(7) implemented interfaces
|
实现有哪些interfaces
|
getInterfaces()
|
Class[]
|
(8) inner classes
|
内部classes
|
getDeclaredClasses()
|
Class[]
|
(8') outer class
|
如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。
|
getDeclaringClass()
|
Class
|
(9) constructors
|
构造函数getDeclaredConstructors()
|
不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
|
Constructor[]
|
(10) methods
|
操作函数getDeclaredMethods()
|
不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
|
Method[]
|
(11) fields
|
字段(成员变量)
|
getDeclaredFields()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。
|
Field[]
|
图3:Java class大卸八块后(如图2),每一块所对应的Reflection API。
Model.java
package RefInt;
import java.io.Serializable;
import java.util.Date;
publicclass Model implements Serializable {
privatestaticfinallongserialVersionUID = -162798607158235676L;
publicstatic String id = "111111";
public String name = "haha";
privateintage ;
private Date b;
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age = age;
}
public Date getB() {
returnb;
}
publicvoid setB(Date b) {
this.b = b;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
}
RefInt.java
package RefInt;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
publicclass RefInt {
publicstaticvoid main(String[] args) {
System.out.println("f_1()");
f_1();
System.out.println("f_2()");
f_2();
System.out.println("f_3()");
f_3();
System.out.println("f_4()");
f_4();
System.out.println("getArrayByIndex()");
int[] a = {10,2,3,5};
String[] s = {"aabc","aaabc","def","f"};
// 数组排序
Arrays.sort(s);
System.out.println(getArrayByIndex(s,0));
System.out.println(getArrayByIndex(a,0));
System.out.println(getArrayByIndex(a,3));
Arrays.sort(a);
System.out.println(getArrayByIndex(a,0));
System.out.println(getArrayByIndex(a,3));
Array.set(a, 0, -1);
System.out.println(getArrayByIndex(a,0));
}
/**
*获得数组o下标为index的值
*@paramo
*@paramindex
*@return
*/
publicstatic Object getArrayByIndex(Object o , int index) {
return Array.get(o, index);
}
/**
*通过类名得到类描述对象
*通过类描述对象获得类模式(此类为public)
*/
publicstaticvoid f_4() {
try {
Class class_my = Class.forName("RefInt.Model");
int m = class_my.getModifiers();
System.out.println(class_my.getModifiers());
if (Modifier.isPublic(m))
System.out.println("public");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
/**
*通过类名得到类描述对象
*通过类描述对象获得属性对象列表并显示其属性
*/
publicstaticvoid f_3() {
try {
Class class_my = Class.forName("RefInt.Model");
// 只能得到属性是public的Field
Field[] publicFields = class_my.getFields();
for (int i = 0; i < publicFields.length; i++) {
String fieldName = publicFields[i].getName();
Class typeClass = publicFields[i].getType();
String fieldType = typeClass.getName();
System.out.println("Name: " + fieldName + ", Type: " + fieldType);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
*通过实体对象获得类描述对象
*通过累描述对象获得指定属性对象
*通过属性对象实例得到属性名和属性值
*/
publicstaticvoid f_2() {
Model model = new Model();
//属性必须是public,否则抛出NoSuchFieldException异常
String sfiled = "name";
Class class_my = model.getClass();
try {
Field filed = class_my.getField(sfiled);
System.out.println(filed.getName());
System.out.println(filed.get(model));
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
*通过类名获得实体对象
*通过属性名称获取实体对象属性值
*/
publicstaticvoid f_1() {
try {
Class cla = Class.forName("RefInt.Model");
Object o = cla.newInstance();
String methodName = "getName";
Method m = cla.getMethod(methodName, (Class[])null);
System.out.println(m.invoke(o, (Object[])null));
methodName = "getAge";
m = cla.getMethod(methodName, (Class[])null);
System.out.println(m.invoke(o, (Object[])null));
methodName = "getB";
m = cla.getMethod(methodName, (Class[])null);
System.out.println(m.invoke(o, (Object[])null));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
Intro.java
package RefInt;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
publicclass Intro {
publicstaticvoid main(String[] args) {
Model m = new Model();
try {
// 从其所在位置开始停止分析的基类。stopClass 或其基类中的所有方法/属性/事件都将在分析中被忽略。
BeanInfo beanInfor = Introspector.getBeanInfo(m.getClass(),Object.class);
PropertyDescriptor[] p = beanInfor.getPropertyDescriptors();
for(int i=0;i<p.length;i++){
System.out.println(p[i].getName()+"="+
p[i].getReadMethod().invoke(m,(Object[])null));
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
相关推荐
Java反射机制是Java平台核心API的一部分,通过它我们可以获取类的内部信息,包括类名、方法名、参数类型等,并能在运行时动态调用类的方法,创建类的对象,甚至修改类的属性。本文将深入探讨Java反射机制及其应用。 ...
8. **自省与Java注解**: - Java注解提供元数据,而反射可以用来读取这些元数据,实现代码的自动化处理或验证。 9. **反射与泛型**: - 尽管Java的泛型在编译后会被擦除,但反射仍可以获取到关于泛型的一些信息,...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、对象等的内部信息。这一机制的核心在于Java.lang.reflect包,它提供了Class、Constructor、Method和Field等类,使得我们可以...
Java反射是Java语言提供的一种强大的动态编程特性,它允许程序在运行时检查并操作类、接口、对象等的内部信息。这一概念最早由Smith在1982年提出,核心思想是程序能够自省,即在运行时可以访问、检测和修改自身的...
总结来说,Java反射机制提供了一种强大的手段,让我们可以在运行时动态地获取类的信息并操作对象,这对于实现元编程、插件化、代码自省等高级功能具有重要作用。在学习和使用时,我们需要理解其原理,合理运用,避免...
Java中的反射功能允许运行中的程序对自身进行检查,并能直接操作程序的内部属性,即所谓的“自省”能力。这是Java区别于其他编程语言如Pascal、C或C++的一个重要特性,因为在这些语言中无法直接获取函数定义等信息。...
总结来说,Java反射机制是Java语言的一个重要特性,它使得程序能够在运行时动态地获取类的信息并进行操作,提高了代码的通用性和适应性。在实际开发中,反射机制常用于框架设计、插件系统、数据持久化等领域,但同时...
总的来说,Java反射机制为Java语言的动态性和自省能力提供了技术基础,使得开发者能够在运行时操作类和对象的属性、方法等,极大地增强了程序设计的灵活性。然而,这种灵活性也应被合理使用,避免过度依赖反射带来的...
Java反射机制是Java编程语言的一项独特特性,它赋予了Java程序在运行时检查自身结构与行为的能力。这种能力不仅体现在对类、字段、方法、构造器等的自省上,还能直接操作这些元素,实现动态加载类、创建对象、调用...
JAVA反射机制是Java语言提供的一种基础功能,赋予程序在运行时自省(检查和修改其自身状态)的能力。具体来说,Java反射机制允许程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个...
### Java反射机制的研究 #### 反射机制简介 Java反射机制是Java语言提供的一种能够使程序在运行时访问自身信息并进行操作的功能。通过反射,Java程序可以动态地获取类的信息(如方法、属性等)并对其进行操作。...
Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制是通过`java.lang.Class`类和`java.lang.reflect`包来实现的。这篇博文主要探讨...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。在Java中,反射机制提供了强大的能力,能够让我们在编译阶段不知道类名的情况下,实例化对象、访问成员变量和调用...
《JAVA反射在行动》这本书由Ira R. Forman和Nate Forman撰写,由MANNING出版社出版,是一本深入探讨Java反射机制及其应用的权威指南。反射是Java语言的一项强大特性,允许运行时检查类的信息并操作类的对象,这在很...
《Java反射技术实战》这本书由Ira R. Forman和Nate Forman撰写,由MANNING出版社出版,是一本深入探讨Java反射机制及其在实际编程中的应用的专业书籍。本书的独特之处在于它不仅展示了反射机制所能实现的各种酷炫...
Java反射机制是Java语言提供的一个强大的功能,它允许在运行时动态地访问和修改类的属性和方法。在本文中,我们将学习如何使用Java反射来操作数组,包括创建数组、给数组赋值和输出数组元素等内容。 首先,我们来看...
Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。反射的概念最早由Smith在1982年提出,指的是程序能够自省,即检查自身状态和行为的能力。在Java中,反射机制提供了一种...
2. 自省与反射的区别 自省(Introspection)是反射的一个子集,它主要用于检查对象的类型和属性。在Java中,自省通常涉及到`java.beans`包中的类,如`PropertyDescriptor`和`BeanInfo`,用于获取和设置对象的属性值...
"JAVA的内省机制(introspector)与反射机制(reflection)" JAVA 的内省机制(introspector)和反射机制(reflection)是两个重要的概念,在 JAVA 编程中扮演着至关重要的角色。那么,什么是内省机制和反射机制?它们...
讲解JAVA反射机制,如何在运行时动态获取类的信息和调用方法,以及注解的使用,理解其在代码自省和元编程中的应用。 第十讲:JAVA高级特性与实战 涵盖JAVA的高级特性,如枚举、泛型、Lambda表达式等,并结合实际...