通过类的名称(一个字符串)去引用类的对象的一种方法,如:在jdbc中,sun只是定义了访问数据库的接口,但没有去实现他,接口的实现是由各数据库产家实现的,为了初始化数据库驱动需要使用下面的语句:
Class.forName("com.mysql.jdbc.Driver");//这里com.mysql.jdbc.Driver这个类事先不知道
又如:我们编写一个servlet网页,于是在web.xml中加入一个servlet配置:
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>com.ldz.test.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
这时servlet容器(如tomcat)就要通过web.xml中的字符串"com.ldz.test.Test"去初始化Test这个类,这就是典型的反射调用。
Class.forName("com.mysql.jdbc.Driver");//这里com.mysql.jdbc.Driver这个类事先不知道
又如:我们编写一个servlet网页,于是在web.xml中加入一个servlet配置:
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>com.ldz.test.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
这时servlet容器(如tomcat)就要通过web.xml中的字符串"com.ldz.test.Test"去初始化Test这个类,这就是典型的反射调用。
你可以直接通过反射 通过java类得名字和方法的名字就可以获得该方法的返回数据。
具体什么是反射,本文这里不再叙述,网上有很多的解释。本人结合自己的理解和应用给出几个例子和用法,希望对读者能有帮助。由于本人能力也有限,有解释不到之处,请读者们谅解。
在研究反射之前,首先要了解几个重要的类:java.lang.Class,java.lang.reflect中的Method、Field、Constructor等classes。如果还不太清楚,请先查阅一下java的api。
反射有两个缺点:1)第一个是性能问题;2)第二个是维护困难。
反射的优点:动态的操纵代码,非常灵活
一 基于Constructor的反射
在研究反射之前,首先要了解几个重要的类:java.lang.Class,java.lang.reflect中的Method、Field、Constructor等classes。如果还不太清楚,请先查阅一下java的api。
反射有两个缺点:1)第一个是性能问题;2)第二个是维护困难。
反射的优点:动态的操纵代码,非常灵活
一 基于Constructor的反射
- import java.lang.reflect.Constructor;
- public class TestMain {
- public static void main(String[] args) throws Exception {
- Class[] types = new Class[] { String.class, String.class, int.class };
- Constructor cons = TestCon.class.getConstructor(types);
- Object[] arguments = new Object[] { "huaxin", "phl", 1 };
- TestCon tc = (TestCon) cons.newInstance(arguments);
- }
- }
- class TestCon {
- // 构造方法必须为public
- private int a;
- private String s1;
- private String s2;
- public TestCon(String s1, String s2, int a) {
- this.a = a;
- this.s1 = s1;
- this.s2 = s2;
- System.out.println("a=" + this.a + ";s1=" + this.s1 + ";s2=" + this.s2);
- }
- }
二 基于Field反射 // 能获取某个类的属性值
- package test;
- import java.lang.reflect.Field;
- public class TestMain {
- public static void main(String[] args) throws Exception {
- //获得对象的属性
- TestCon tc = new TestCon(1);
- // 只有public的字段才能获取
- Field field = tc.getClass().getField("b");
- int value = field.getInt(tc) + 1;
- field.setInt(tc, value);
- System.out.println(tc.b);
- //获得类的静态属性
- Class tc2 = Class.forName("test.TestCon");
- Field field2 = tc2.getField("a");
- System.out.println(field2.getInt(tc2));
- }
- }
- class TestCon {
- public int b;
- public static int a = 10;
- public TestCon(int b) {
- this.b = b;
- }
- }
三 基于Method的反射
- import java.lang.reflect.Method;
- public class TestMain {
- public static void main(String[] args) throws Exception {
- Object o = Class.forName("test.TestCon").newInstance();
- Class[] type = new Class[] { int.class, int.class, String.class };
- Method m = o.getClass().getMethod("add", type);
- Object[] arguments = new Object[] { 1, 1, "result" };
- m.invoke(o, arguments);
- }
- }
- class TestCon {
- public void add(int a, int b, String name) {
- System.out.println(name + " is " + (a + b));
- }
- }
四 数组的反射
- import java.lang.reflect.Array;
- public class TestMain {
- public static void main(String[] args) throws Exception {
- int[] as = new int[5];
- for (int i = 0; i < 5; i++) {
- as[i] = i;
- }
- Object array = as;
- int size = 10;
- //反射创建数组
- Class type = array.getClass().getComponentType();
- Object array2 = Array.newInstance(type, size);
- //复制数组
- System.arraycopy(array, 0, array2, 0, Math.min(Array.getLength(array), size));
- int[] as2 = (int[]) array2;
- System.out.println(as2.length);
- //得到数组某个元素
- //Array.get(array,index);
- }
- }