反射,总而言之当初我字面上并没看明白什么意思。个人认为“反射”名字取得不够好,应该叫Java选择机制
就像jQuery选择器一样,能够在运行过程中获取dom节点的所有信息。
java反射机制也是一样,就是说能在程序运行过程中获取和调用任意一个类的所有方法属性。
java中已经提供了专门处理反射的包java.lang.reflect
下面就先说说类对象
例1:类对象创建的三个方法
LoadClass.java
package com.zero; public class LoadClass { public static void main(String [] args) throws ClassNotFoundException { /* * 类对象创建的三种方法(类对象都是Class的实例) */ Class t1 = null; Class t2 = null; Class t3 = null; t1 = Class.forName("com.zero.Test"); t2 = new Test().getClass(); t3 = Test.class; } } //测试类 class Test { //静态语句块,类加载时运行,只运行一次 static{ System.out.println("类加载中"); } }
例1运行结果:类加载中
以上类对象创建的方法中,最常用的是Class.forName("xxx")这种方法,一般jdbc连接数据库加载jdbc驱动使用的就是这个方法。
进入正题吧,如下案例
例2:java反射机制
ReflectTest.java
package com.zero; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class ReflectTest { public static void main(String [] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class test2 = Class.forName("com.zero.TestReflect");//类对象创建 TestReflect tt = (TestReflect)test2.newInstance();//实例化testReflect对象 Method [] methods = test2.getMethods();//获取类对象成员方法 System.out.println("---------类成员方法如下-------------"); for(Method m:methods){ int mo = m.getModifiers();//获取方法修饰符,这里获取的是int类型,需要使用Modifier.toString()转换 System.out.print(Modifier.toString(mo) + " "); System.out.print(m.getReturnType().getName()+" ");//方法发返回类型 System.out.print(m.getName());//方法名 Class [] parameters = m.getParameterTypes();//方法的所有参数类型 System.out.print("("); int i = 0; for(Class parameter:parameters){ System.out.print(parameter.getName()+" " + "arg" + i++); if(i < parameters.length) { System.out.print(", "); } } System.out.println("){}"); } System.out.println("---------类成员变量如下-------------"); Field[] fie = test2.getDeclaredFields(); for (Field ff :fie){ int dd = ff.getModifiers();//变量修饰符 System.out.print(Modifier.toString(dd) + " "); System.out.print(ff.getType().getName() + " ");//变量类型 System.out.println(ff.getName());//变量名 } System.out.println("---------printParameter()方法调用-------------"); for(Method m:methods){ if(m.getName().equals("printParameter")){//调用方法名称为printParameter的方法 String re = (String)m.invoke(tt);//执行方法 System.out.println("方法返回:" + re); } } } } class TestReflect { static{ System.out.println("---------类加载中------------"); } //成员变量 private int a; private String b; private float c; public void init() { this.a = 100; this.b = "china"; this.c = 0.77f; } public void printParameter() { init (); System.out.println("a=" + a + " b=" + b + " c =" + c); } public String ex() { this.b = "chinese"; System.out.println(b); return this.b; } }
运行结果:
---------类加载中------------ ---------类成员方法如下------------- public void init(){} public java.lang.String ex(){} public void printParameter(){} public final void wait(){} public final void wait(long arg0, int arg1){} public final native void wait(long arg0){} public native int hashCode(){} public final native java.lang.Class getClass(){} public boolean equals(java.lang.Object arg0){} public java.lang.String toString(){} public final native void notify(){} public final native void notifyAll(){} ---------类成员变量如下------------- private int a private java.lang.String b private float c ---------printParameter()方法调用------------- a=100 b=china c =0.77 方法返回:null
例2中可以看到,在程序运行中java可以根据类的名字获取类的所有信息同时还能调用类中的任意方法(当然,案例中我只写了片面,比如获取类实现的接口、抛出的异常等等都是可以的,这个自己去看api文档就可以了)——其实这个就是java的反射机制^_^
注:在类中方法、方法类型、成员变量类型、名称等都是一个对象
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/huangzirong822/article/details/47294299