JAVA 反射机制是Java 被视为动态(或准动态)语言的一个关键性质。这个机制允许程式在运行时通过Reflection APIs 取得任何一个已知名称的class 的内部资讯,包括其modifiers(诸如public, private,static 等等)、superclass(例如Object)、interfaces(例如Cloneable),也包括fields 和methods 的所有资讯, 并在运行时调用任意一个对象的方法;生成动态代理。下面以一段代码来看一下主要的Reflection APIs,代码中有相应的注释。
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Goods
{
private String id;
private double price;
public Goods(){
System.out.println("it is a pen");
}
public Goods(String s1,String s2){
System.out.println(s1+"*"+s2);
}
public String getId()
{
System.out.println(id);
return id;
}
public void setId(String id)
{
this.id = id;
}
public String addName(String str1,String str2){
return str1+str2;
}
/**
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws NoSuchFieldException
* @功能描述
* @输入参数
* @反馈值
*/
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException
{
// TODO Auto-generated method stub
String str = "com.xtlh.sinye.Goods";
Class c = Class.forName(str);
Object obj = c.newInstance();//初始化一个Goods的对象
/**
* //这里设置属性的值 调用setId()方法,类型用Class[],参数用Object[]
*/
Method m = c.getMethod("setId",new Class[]{Class.forName("java.lang.String")});
m.invoke(obj,new Object[]{"it's apple"});
System.out.println("---------------------------------------------------------------------");
/**
* //这里是里获取属性的值 调用getId()方法
*/
m = c.getMethod("getId",new Class[]{});
m.invoke(obj,new Object []{});
System.out.println("---------------------------------------------------------------------");
/**
* //获得类中声明的方法
*/
Method me[] = c.getDeclaredMethods();
for(int i=0;i<me.length;i++){
System.out.println("method["+i+"]="+me[i].toString());
}
System.out.println("---------------------------------------------------------------------");
/**
* //模拟 instanceof 操作符
*/
boolean b1 = c.isInstance(new Integer(34));
System.out.println("Goods is a instance of Integer ? "+b1);
boolean b2 = c.isInstance(new Goods());//这里调用了无参的构造方法
System.out.println("Goods is a instance of Goods ? "+b2);
System.out.println("---------------------------------------------------------------------");
/**
* //找出类的方法,类的名称,类的方法的参数,类的方法的返回类型
*/
Method med[] = c.getDeclaredMethods();
Method med1[] = c.getMethods();//从字面意思可以看出来,这里找到所有的方法,即可以找到继承来的方法等
for(int i=0;i<med.length;i++){
Method mee = med[i];
System.out.println("method # "+i+" name="+mee.getName());
System.out.println("declaring class ="+mee.getDeclaringClass());
//方法的参数类型
Class pvec[] = m.getParameterTypes();
for(int j=0;j<pvec.length;j++){
System.out.println("parameter # "+j+" ="+pvec[j]);
}
//方法的异常
Class evec[] = m.getExceptionTypes();
for (int j = 0; j < evec.length; j++){
System.out.println("exception #" + j + " " + evec[j]);
}
//方法的返回类型
System.out.println("return type = " + mee.getReturnType());
}
System.out.println("---------------------------------------------------------------------");
/**
* //获取类的构造函数
*/
Constructor ctorlist[] = c.getDeclaredConstructors();
for(int i=0;i<ctorlist.length;i++){
Constructor cons = ctorlist[i];
System.out.println("Constructor #"+i+" name="+cons.getName());
Class[] consParaType = cons.getParameterTypes();//获得构造函数的参数类型
if(consParaType.length==0){
System.out.println("Constructor have no parameters");
}else{
for(int j=0;j<consParaType.length;j++){
System.out.println("Constructor Parameter type #"+j+" name="+consParaType[j]);
}
}
}
System.out.println("---------------------------------------------------------------------");
/**
* //获取类的属性
*/
Field fieldlist[] = c.getDeclaredFields();
for(int i=0;i<fieldlist.length;i++){
Field field = fieldlist[i];
System.out.println("Filed #"+i+" name="+field.getName());//属性名称
System.out.println("Filed #"+i+" type="+field.getType());//属性类型
int mod = field.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));//属性的修饰符 private/public/protected
}
System.out.println("---------------------------------------------------------------------");
/**
* //根据方法的名称来执行方法
*/
Class cls = Class.forName("com.xtlh.sinye.Goods");
Class partypes[] = new Class[2];
partypes[0] = String.class;//更多类型 Long.TYPE Integer.TYPE,或者使用Long.class、Integer.class
partypes[1] = Class.forName("java.lang.String");
Method meth = cls.getMethod("addName", partypes);
Goods goods = new Goods();
Object arglist[] = new Object[2];
arglist[0] = new String("love");
arglist[1] = new String("grape");
Object retobj = meth.invoke(goods, arglist);
String retval = (String) retobj;
System.out.println(retval);
System.out.println("---------------------------------------------------------------------");
/**
* 创建对象,根据指定的参数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象,而不是在编译的时候创建对象,这一点非常有价值
*/
Class clss = Class.forName("com.xtlh.sinye.Goods");
Class partypess[] = new Class[2];
partypess[0] = String.class;
partypess[1] = String.class;
Constructor ct = clss.getConstructor(partypess);
Object arglists[] = new Object[2];
arglists[0] = new String("hello");
arglists[1] = new String("orange");
Object retobjs = ct.newInstance(arglists);
System.out.println("---------------------------------------------------------------------");
/**
* //改变属性的值
*/
Class ccc = Class.forName("com.xtlh.sinye.Goods");
Field fld = ccc.getDeclaredField("price");
Goods goods1 = new Goods();
System.out.println("price = " + goods1.price);
fld.setDouble(goods1, 25.0);
System.out.println("price = " + goods1.price);
System.out.println("---------------------------------------------------------------------");
/**
* //简单使用数组,创建了 10 个单位长度的 String 数组,为第 5 个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来
*/
Class cla = Class.forName("java.lang.String");
Object arr = Array.newInstance(cla, 10);
Array.set(arr, 5, "hello Watermelon");
String s = (String) Array.get(arr, 5);
System.out.println(s);
System.out.println("---------------------------------------------------------------------");
/**
* //复杂数组使用,例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后,arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素,即长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。
注意创建数组时的类型是动态的,在编译时并不知道其类型。
*/
int dims[] = new int[]{5, 10, 15};
Object array = Array.newInstance(Integer.TYPE, dims);
Object arrobj = Array.get(array, 3);
Class cl = arrobj.getClass().getComponentType();
System.out.println(cl);
arrobj = Array.get(arrobj, 5);
Array.setInt(arrobj, 10, 37);
int arrcast[][][] = (int[][][]) array;
System.out.println(arrcast[3][5][10]);
}
}
分享到:
相关推荐
### Java的反射机制及其实际应用 #### 一、引言 ...总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,避免滥用造成不必要的性能损失或安全风险。
通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 #### 二、Java反射机制简介 Java反射机制允许程序在运行时获取类的信息,这使得Java具有了一定程度上的动态性。具体来说,Java反射机制...
### Java反射机制应用详解 #### 一、Java反射机制简介 Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建...
### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至...对于初学者而言,了解并掌握Java反射机制的基本原理和应用场景是非常有益的。
Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中...在实践中学习,你会更好地理解Java反射机制的威力和应用场景。
### 反射实例—JAVA反射机制 #### 一、反射概念及原理 ...总结而言,Java反射机制是构建灵活、可扩展应用程序的强大工具。然而,在使用反射时,开发者应当权衡其带来的好处和潜在的风险,确保合理有效地利用这一特性。
Java反射机制还涉及到注解处理,可以使用`Annotation`接口及其子类来获取和处理类、方法、字段上的注解信息。这对于实现元编程、AOP(面向切面编程)和自定义注解处理器非常有用。 总的来说,Java反射机制为程序员...
这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...
### Java反射机制详解 #### 一、反射机制是什么 反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以...
通过这个例子,新手可以学习到如何使用Java反射机制来增强代码的动态性,以及如何设计可扩展的系统。反射在很多场景下都很有用,例如在插件系统、序列化、动态代理等领域都有广泛应用。然而,需要注意的是,反射也...
Java反射机制允许运行中的程序检查自身,并能直接操作程序的内部属性。这是其他许多编程语言(如Pascal、C或C++)不具备的能力。 **1.1 Reflection的工作机制** 为了展示反射如何工作,我们来看一个简单的例子: ...
### Java反射机制的原理及在Android下的简单应用 #### 一、Java反射机制的基本概念 反射(Reflection)是指程序在运行时能够访问、检测和修改它自身的能力。这种能力使得程序能够动态地获取自身的结构信息并操作...
Java反射机制是一项强大而灵活的功能,它使得Java程序能够在运行时动态地检查和操作类及其成员。在实际开发中,反射机制在框架设计、动态代理、插件化开发、单元测试和配置与注解处理等方面有着广泛的应用。然而,...
Java 反射机制详解 Java 反射机制是 Java 语言提供的一种强大的工具,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并进行操作。这种能力使得 Java 应用程序更加灵活,能够在运行时发现和修改自身...
### Java反射机制深入理解 #### 一、反射机制概述 Java反射机制是一种强大的工具,它允许程序在运行时检查和操作任何类、方法、构造函数和字段等元素。这种能力对于构建灵活的应用程序和框架非常有用,特别是那些...
下面是一个简单的Java反射机制的实现例子: ```java import java.lang.reflect.Field; public class ReflectionExample { private String privateField = "默认值"; public static void main(String[] args) ...
本文将深入探讨Java反射机制的原理及其在实际开发中的应用。 首先,我们要理解什么是反射。反射是指在运行时,程序能够获取关于类、接口、字段和方法等信息,并且能够动态地调用方法、创建对象的能力。在Java中,`...