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