java.lang.reflect提供類和接口,以獲取關於類和對象的反射信息。在安全限制內,反射容許編程訪問關於加載類的字段、方法和構造方法的信息,並容許使用反射字段、方法和構造方法對對象上的基本對等項進行操做。java
java.lang.reflect包下經常使用的類有編程
java.lang.reflect通常都是配合java.lang.Class一塊兒使用。數組
經常使用的方法有安全
getName():得到類的完整名字;
getFields():得到類的public類型的成員變量;
getDeclaredFields():得到類的全部成員變量;
getMethods():得到類的public類型的方法;
getDeclaredMethods():得到類的全部方法;函數
getMethod(String name, Class[] parameterTypes):得到類的特定方法,name參數指定方法的名字,parameterTypes 參數指定方法的參數類型;this
getConstructors():得到類的public類型的構造方法;
getConstructor(Class[] parameterTypes):得到類的特定構造方法,parameterTypes 參數指定構造方法的參數類型; code
實例對象
stu.java繼承
package cn.iborder.javaBean; import java.util.Date; public class Stu { public int id; private String name; private int age; public Stu(){ super(); } public Stu(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } private Stu(String name) { super(); this.id = 88888; this.name = name; this.age = 100; } private int getId() { return id; } private void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void sayHello(String name,Date date) { System.out.println(date+":"+this.id+this.name+"你好,我是"+name); } }
TestReflect2.java接口
package cn.iborder.test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class TestReflect2 { public static void main(String[] args) throws ClassNotFoundException { // TODO Auto-generated method stub Class class1 = Class.forName("cn.iborder.javaBean.Stu"); System.out.println("類名:"+class1.getName()); System.out.println("包名:"+class1.getPackage()); System.out.println("父類名:"+class1.getSuperclass().getName()); System.out.println("========成員變量========"); //成員變量 System.out.println("xxxx所有成員變量xxxx"); Field[] fields = class1.getDeclaredFields();//得到全部成員變量 for (Field field : fields) { System.out.println(field.getType().getSimpleName() +" "+ field.getName()); } System.out.println("xxxx公有成員變量xxxx"); Field[] fields1 = class1.getFields(); for (Field field : fields1) { System.out.println(field.getType().getSimpleName() +" "+ field.getName()); } System.out.println("========成員方法========"); //成員方法 System.out.println("xxxx所有成員方法xxxx"); Method[] methods = class1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()+"()"); } System.out.println("xxxx公有成員方法xxxx"); Method[] methods1 = class1.getMethods(); for (Method method : methods1) { System.out.println(method.getName()+"()"); } System.out.println("========構造方法========"); //構造方法 System.out.println("xxxx所有構造方法xxxx"); Constructor[] constructors = class1.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor.getName()+"()"); } System.out.println("xxxx公有構造方法xxxx"); Constructor[] constructors1 = class1.getConstructors(); for (Constructor constructor : constructors1) { System.out.println(constructor.getName()+"()"); } } }
運行結果
類名:cn.iborder.javaBean.Stu 包名:package cn.iborder.javaBean 父類名:java.lang.Object ========成員變量======== xxxx所有成員變量xxxx int id String name int age xxxx公有成員變量xxxx int id ========成員方法======== xxxx所有成員方法xxxx getAge() setAge() sayHello() setId() getName() getId() setName() xxxx公有成員方法xxxx getAge() setAge() sayHello() getName() setName() getClass() hashCode() equals() toString() notify() notifyAll() wait() wait() wait() ========構造方法======== xxxx所有構造方法xxxx cn.iborder.javaBean.Stu() cn.iborder.javaBean.Stu() cn.iborder.javaBean.Stu() xxxx公有構造方法xxxx cn.iborder.javaBean.Stu() cn.iborder.javaBean.Stu()
經過反射建立新的類對象,有兩種方式:
Class.newInstance() 只可以調用無參構造函數(要求被調用的構造函數是可見的,也即必須是public類型的; );
Constructor.newInstance() 能夠根據傳入的參數,調用任意構造構造函數(在特定的狀況下,能夠調用私有的構造函數)。
實例
TestReflect3.java
package cn.iborder.test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; import cn.iborder.javaBean.Stu; public class TestReflect3 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { // TODO Auto-generated method stub Class<?> class1 = Class.forName("cn.iborder.javaBean.Stu"); //調用public類型無參構造函數建立對象 Stu stu1 = (Stu) class1.newInstance(); System.out.println(stu1.getName()); //調用public類型有參構造函數建立對象 Constructor<?> constructor = class1.getConstructor(new Class[]{int.class, String.class, int.class}); Stu stu2 = (Stu) constructor.newInstance(new Object[]{10086,"李四",23}); System.out.println(stu2.getName()); Object object = constructor.newInstance(new Object[]{10010,"王五",13}); Method method = class1.getMethod("sayHello", new Class[]{String.class,Date.class}); method.invoke(object, new Object[]{"喬布斯",new Date()}); Field field = class1.getField("id"); field.set(object, 10086); method.invoke(object, new Object[]{"喬布斯",new Date()}); //調用private類型有參構造函數建立對象 Constructor<?> constructor2 = class1.getDeclaredConstructor(new Class[]{String.class}); constructor2.setAccessible(true);// 功能是啓用或禁用安全檢查,true表示容許調用 Object object2 = constructor2.newInstance(new Object[]{"李彥宏"}); method.invoke(object2, new Object[]{"喬布斯",new Date()}); } }
運行結果
null 李四 Fri Oct 21 17:01:12 CST 2016:10010王五你好,我是喬布斯 Fri Oct 21 17:01:13 CST 2016:10086王五你好,我是喬布斯 Fri Oct 21 17:01:13 CST 2016:88888李彥宏你好,我是喬布斯
Accessable屬性是繼承自AccessibleObject 類. 功能是啓用或禁用安全檢查。
AccessibleObject 類是 Field、Method 和 Constructor 對象的基類。它提供了將反射的對象標記爲在使用時取消默認 Java 語言訪問控制檢查的能力。對於公共成員、默認(打包)訪問成員、受保護成員和私有成員,在分別使用 Field、Method 或 Constructor 對象來設置或得到字段、調用方法,或者建立和初始化類的新實例的時候,會執行訪問檢查。 在反射對象中設置 accessible 標誌容許具備足夠特權的複雜應用程序(好比 Java Object Serialization 或其餘持久性機制)以某種一般禁止使用的方式來操做對象。 public void setAccessible(boolean flag) throws SecurityException