dang_java 发表于 2013-2-4 23:00:20

小谈JAVA中的反射知识

反射软件包:java.lang.reflect,提供类和接口,以获取关于类和对象的反射信息。
反射的作用:在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对对象上的基本对等项进行操作。
接口摘要
AnnotatedElement: 表示目前正在此 VM 中运行的程序的一个已注释元素。
GenericArrayType GenericArrayType: 表示一种数组类型,其组件类型为参数化类型或类型变量。
GenericDeclaration: 声明类型变量的所有实体的公共接口。
InvocationHandler InvocationHandler: 是代理实例的调用处理程序 实现的接口。
Member: 成员是一种接口,反映有关单个成员(字段或方法)或构造方法的标识信息。
ParameterizedType ParameterizedType: 表示参数化类型,如 Collection<String>。
Type Type: 是 Java 编程语言中所有类型的公共高级接口。
TypeVariable<D extends GenericDeclaration> TypeVariable: 是各种类型变量的公共高级接口。
WildcardType WildcardType: 表示一个通配符类型表达式,如 ?、? extends Number 或 ? super Integer。  
类摘要
AccessibleObject AccessibleObjec:t 类是 Field、Method 和 Constructor 对象的基类。
Array Array: 类提供了动态创建和访问 Java 数组的方法。
Constructor<T> Constructor: 提供关于类的单个构造方法的信息以及对它的访问权限。
Field Field: 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
Method Method: 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
Modifier Modifier: 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。
Proxy Proxy: 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
ReflectPermission: 反射操作的 Permission 类。
 
异常摘要
InvocationTargetException InvocationTargetException: 是一种包装由调用方法或构造方法所抛出异常的经过检查的异常。
MalformedParameterizedTypeException: 当反射方法遇到语义错误的参数化类型,而反射方法需要实例化该类型时,抛出该异常。
UndeclaredThrowableException: 如果代理实例的调用处理程序的 invoke 方法抛出一个经过检查的异常(不可分配给 RuntimeException 或 Error 的 Throwable),且该异常不可分配给该方法(在代理实例上调用该方法,并将其指派到调用处理程序)的 throws 子句中声明的任何异常类,则由代理实例上的方法调用抛出此异常。
 
错误摘要
GenericSignatureFormatError: 当需要解释类型、方法或构造方法的一般签名信息的反射方法遇到语法错误的签名属性时,抛出该错误。
---------------------------------------------------------------------------------
实例说明:
用反射机制得到指定类中的属性,构造方法,方法。
有 userBean类如下:
---------------------------------------------------------------------------------
package com.it97.test.reflex;
public class UserBean {
 private String userName;
 private String password;
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 public UserBean() {
  System.out.println("我是无参数的构造方法");
 }
 public UserBean(String userName, String password) {
  this.userName = userName;
  this.password = password;
  System.out.println("我是两个参数的构造方法");
 }
}
---------------------------------------------------------------------------------
实现类如下:
---------------------------------------------------------------------------------
package com.it97.test.reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestClass {
 public static void main(String[] args) throws SecurityException,
   NoSuchMethodException, IllegalArgumentException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException {
  //得到Class实例
  //Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同 
  //元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为  
  //Class 对象。
  Class c = UserBean.class;
  
  // getDeclaredMethods()   返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和//私有方法,但不包括继承的方法。
  System.out.println("对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法(不包括继承的方法):");
  System.out.println("数量:" + c.getDeclaredMethods().length);
  for (Method m : c.getDeclaredMethods()) {
   System.out.println("得到的方法名:" + m.getName());
  }
  System.out.println("-------------------------------------------------------");  
  //getMethods()返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承//的那些的类或接口)的公共 member 方法。
  System.out.println("对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方//法:");
  Method[] methods = c.getMethods();
  System.out.println("数量:" + methods.length);
  for (Method m : methods) {
   System.out.println("得到的方法名:" + m.getName());
  }
  
  //getDeclaredMethod(String name, Class... parameterTypes) 
  // 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
  Method getUserName = c.getDeclaredMethod("getUserName", null);
  //激活得到的方法
  getUserName.invoke(c.newInstance(), null);
  
  
  
  
  
  
  System.out.println("-------------------------------------------------------");
  //getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
  Constructor[] cons = c.getConstructors();
  System.out.println("对象反映此 Class 对象所表示的类的所有公共构造方法,数量:" + cons.length);
  for (Constructor con : cons) {
   System.out.println("得到的构造方法名称:" + con.getName());
  }
  // 分别构造两个UserBean对象 一个使用无参构造方法,一个使用带二个参数的构造方法
  // 得到构造方法
  Constructor method1 = c.getDeclaredConstructor(String.class,String.class);
  Constructor method2 = c.getDeclaredConstructor(null);
  // 构造实体对象
  UserBean u = (UserBean) method1.newInstance("a", "b");
  UserBean u2 = (UserBean) method2.newInstance(null);
  System.out.println("-------------------------------------------------------");
  
    
  //getDeclaredFields()返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段,包括公共、保护、默认(包)访问和私//有字段,但不包括继承的字段。
  System.out.println("对象反映此 Class 对象所表示的类或接口所声明的所有字段,数量为:" + c.getDeclaredFields().length);
  for (Field f : c.getDeclaredFields()) {
   System.out.println("属性名称:" + f.getName());
  }
 }
}
---------------------------------------------------------------------------------
 尹当-个人心得
页: [1]
查看完整版本: 小谈JAVA中的反射知识