现在的位置: 首页 > 综合 > 正文

Java的反射机制

2014年03月13日 ⁄ 综合 ⁄ 共 4096字 ⁄ 字号 评论关闭

Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。甚至能够在读写字段,调用运行时选择的类的方法。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。

反射有两个缺点。第一个是性能问题。当用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。

许多应用更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问题。

[基于类的反射]

1、Constructor getConstructor(Class[] params) --> 返回一个由params参数指定的类型所获取的公共 Constructor 构造器对象,它反映此 Class 对象所表示的类的指定公共构造方法

2、Constructor[] getConstructors() --> 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法

3、Constructor getDeclaredConstructor(Class[] params) --> 返回一个由params参数指定的类型所获取的 Constructor 构造器,该对象反映此 Class 对象所表示的类或接口的指定构造方法

4、Constructor[] getDeclaredConstructors() --> 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法

public class A {
  public String f1;
  private String f2 = "a";

  public A() {
    System.out.println("无参构造函数");
  }

 

  public A(String s1, String s2) {
    System.out.println("有参构造函数: String1=" + s1 + ";String2=" + s2);
  }

  public A(String s1, String s2, String s3) {
    System.out.println("有参构造函数: String1=" + s1 + ";String2=" + s2 + ";String3=" + s3);
  }

  public void setF1(String f1){
    this.f1 = f1;
  }

  public String getF1(){
    return this.f1;
  }
}

import java.lang.reflect.*;

 

public class B {
  public void invokeClassConstructor(){
    try {
      Class[] parameters_class = new Class[] {String.class, String.class};
      Constructor cons = A.class.getConstructor(parameters_class);
      Object[] parameters_object = new Object[] {"a", "b"};
      System.out.println(cons.getName());
      A a = (A) cons.newInstance(parameters_object);
    }
    catch (NoSuchMethodException e) {
      System.out.println("找不到匹配的构造函数");
    }
    catch (SecurityException e) {
      System.out.println("存在安全管理问题");
    }
    catch (Exception e) {}
  }
}

[反射增加字段]

1、Field getField(String name) --> 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段

2、Field[] getFields() --> 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段

3、Field getDeclaredField(String name) --> 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段

4、Field[] getDeclaredFields() --> 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段

import java.lang.reflect.*;

 

public class B {
  public void invokeClassField(String name) {
    try{
      Field field = A.class.getDeclaredField(name);
      System.out.println(field.getName());
    }
    catch (NoSuchFieldException e) {
      System.out.println("找不到匹配的字段");
    }
    catch (SecurityException e) {
      System.out.println("存在安全管理问题");
    }
    catch (Exception e) {}
  }
}

[反射增加方法]

1、Method getMethod(String name, Class[] params) --> 返回一个由params参数指定的类型获取由name参数指定的public公共成员方法

2、Method[] getMethods() --> 返回一个类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的所有的public公共成员方法的 Method 数组

3、Method getDeclaredMethod(String name, Class[] params) --> 使用params参数指定的类型返回由name参数所指定的由这个类或接口声明的 Method 方法

4、Method[] getDeclaredMethods() --> 返回一个类或接口所声明的所有的方法(包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法)的 Method 数组

import java.lang.reflect.*;

 

public class B {
  public void invokeClassMethod(String name) {
    try{
      String prop = Character.toUpperCase(name.charAt(0)) + name.substring(1);
      String mname = "set" + prop;
      Class[] types = new Class[] {String.class};
      Method method = A.class.getMethod(mname, types);
      Object[] parameters_object = new Object[] {"b"};
      A a = new A();
      method.invoke(a, parameters_object);
      System.out.println("赋值:b");
      mname = "get" + prop;
      method = A.class.getMethod(mname, null);
      String value = (String)method.invoke(a, null);
      System.out.println("获取值:" + value);
    }
    catch (NoSuchMethodException e) {
      System.out.println("找不到匹配的方法");
    }
    catch (SecurityException e) {
      System.out.println("存在安全管理问题");
    }
    catch (Exception e) {}
  }
}

[反射数组]

1、Class getComponentType() --> 返回表示数组组件类型的 Class。如果此类不表示数组类,则此方法返回 null

import java.lang.reflect.*;

 

public class B {
  public String[] incrementArray(Object array, int size) {
    Class type = array.getClass().getComponentType();
    String[] newArray = (String[]) Array.newInstance(type, size);
    return newArray;
  }
}

调试:

public class C{

  public static void main(String[] args) {
    B b = new B();
    b.invokeClassConstructor();
    b.invokeClassField("f2");
    b.invokeClassMethod("f1");
    String[] array = new String[]{"1","2"};
    array = b.incrementArray(array, 3);
    array[2] = "3";
    System.out.println(array[2]);
  }

}

输出:
com.util.A
有参构造函数: String1=a;String2=b
f2
无参构造函数
赋值:b
获取值:b
3

抱歉!评论已关闭.