介绍
JAVA反射机制是指:在运行状态中,对于任意一个【类】,都能够知道这个类的所有属性和方法;对于任意一个【对象】,都能够调用它的所有属性和方法;这种动态获取类中的信息以及动态调用对象的成员的功能称为java语言的反射机制。 早期,new一个对象的时候,先根据被new的【类的名称】找寻该类的字节码文件, 然后加载进内存,并自动创建该【字节码文件对象】 ,接着创建该字节文件对应的【该类的对象】 现在,同样是先根据被new的【类的名称】找寻该名称的类文件,然后加载进内存,最后通过Class对象的newInstance方法产生【该类的对象】 PS:字节码文件即class文件,是经过编译器预处理过的一种文件,是JAVA的执行文件存在形式。它本身是二进制文件,但是不可以被系统直接执行,而是需要虚拟机解释执行,由于被预处理过,所以比一般的解释代码要快,但是仍然会比系统直接执行的慢。
示例
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { //三种获取对象运行时类的方法 Person person = new Person(); Class<? extends Person> clazz = person.getClass();//获取此 Object 的运行时类 System.out.println(clazz == new Person().getClass());//true。两个对象的运行时类是同一个类 System.out.println(clazz == Person.class);//true。任何数据类型的静态的属性【.class】表示其对应的Class对象 System.out.println(clazz == Class.forName("cn.itcast.bean.Person"));//true。只要通过给定的类的字符串名称即可,这种最常用! System.out.println("----------------------------1-----------------------------"); //通过反射获取【类】的字段信息 Field publicField = clazz.getField("age");//获取全部公有的字段,包含父类的字段。注意私有字段不能通过这种方式获取 Field allField = clazz.getDeclaredField("name");// 获取本类中定义的公有所有字段,包含私有字段。注意不能获取父类的字段。 System.out.println(publicField);//public int cn.itcast.bean.Person.age System.out.println(allField);//private java.lang.String cn.itcast.bean.Person.name System.out.println(Arrays.toString(clazz.getFields()));//[public int cn.itcast.bean.Person.age] System.out.println(Arrays.toString(clazz.getDeclaredFields()));//[age, name] System.out.println("----------------------------2-----------------------------"); //通过反射访问指定【对象】的指定字段 Person person2 = clazz.newInstance(); allField.setAccessible(true);//如果设置为true,则表示可以忽略访问权限的限制,直接访问此成员。设为true可以直接访问私有字段。 allField.set(person2, "包青天");//将【指定对象】上的此 Field 对象表示的【字段】设置为指定的值 String mName = (String) allField.get(person2);//注意:返回的是【指定对象】上此 Field 表示的【字段的值】 System.out.println(mName + "--" + person2.getName());//包青天--包青天 //通过反射获取【类】的方法信息 Method paramMethod = clazz.getMethod("paramMethod", int.class);//获取方法名为paramMethod,参数列表类型为int的方法 Method noParamMethod = clazz.getMethod("show");//获取参数列表为空的方法。注意:不要使用这种形式("show",null) Method privateMethod = clazz.getDeclaredMethod("privateMethod"); System.out.println(paramMethod);//public void cn.itcast.bean.Person.paramMethod(int) System.out.println(noParamMethod);//public void cn.itcast.bean.Person.show() System.out.println(privateMethod);//private void cn.itcast.bean.Person.privateMethod() System.out.println(Arrays.toString(clazz.getMethods()));//和获取字段一样,获取的是包括从父类或父接口继承的全部公有方法 System.out.println(Arrays.toString(clazz.getDeclaredMethods()));//和获取字段一样,获取的是在本类中定义的所有方法 System.out.println("----------------------------3-----------------------------"); //通过反射访问指定【对象】的指定方法 Person person3 = clazz.newInstance(); privateMethod.setAccessible(true);//设为true后可以直接调用对象的私有方法。 privateMethod.invoke(person3);//私有方法:null。对带有【指定参数】的【指定对象】调用由此 Method 对象表示的底层方法 paramMethod.invoke(person3, 1989);//有参方法,参数为:1989 System.out.println("----------------------------4-----------------------------"); //通过反射访问类的构造方法 clazz.newInstance().show();//公共方法。默认调用无参构造函数产生对象 Constructor<? extends Person> publicConstructor = clazz.getConstructor(String.class, int.class); //共有构造方法 publicConstructor.newInstance("小明", 38).paramMethod(2016);//有参方法,参数为:2016。调用指定有参构造函数产生对象 Constructor<? extends Person> privateConstructor = clazz.getDeclaredConstructor(int.class);//私有构造方法 privateConstructor.setAccessible(true); privateConstructor.newInstance(50).paramMethod(50);//有参方法,参数为:50 System.out.println(Arrays.toString(clazz.getConstructors()));//[Person(),Person(int),Person(String,int)] System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));//[Person(),Person(int),Person(String,int)] } }
反射所指向的对象
package cn.itcast.bean; public class Person { public int age;//公共成员 private String name;//私有成员 public String getName() { return name; } public Person() {//无参构造方法 this(0); } private Person(int age) {//私有构造方法 super(); this.age = age; } public Person(String name, int age) {//有参构造方法 super(); this.age = age; this.name = name; } @SuppressWarnings("unused") private void privateMethod() {//私有方法 System.out.println("私有方法:" + name); } public void show() {//公共方法 System.out.println("公共方法"); } public void paramMethod(int num) {//有参方法 System.out.println("有参方法,参数为:" + num); } public static void staticMethod() {//静态成员 System.out.println("静态成员"); } }
运行结果
true true true ----------------------------1----------------------------- public int cn.itcast.bean.Person.age private java.lang.String cn.itcast.bean.Person.name [public int cn.itcast.bean.Person.age] [public int cn.itcast.bean.Person.age, private java.lang.String cn.itcast.bean.Person.name] ----------------------------2----------------------------- 包青天--包青天 public void cn.itcast.bean.Person.paramMethod(int) public void cn.itcast.bean.Person.show() private void cn.itcast.bean.Person.privateMethod() [public java.lang.String cn.itcast.bean.Person.getName(), public void cn.itcast.bean.Person.paramMethod(int), public void cn.itcast.bean.Person.show(), public static void cn.itcast.bean.Person.staticMethod(), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()] [public java.lang.String cn.itcast.bean.Person.getName(), public void cn.itcast.bean.Person.paramMethod(int), public void cn.itcast.bean.Person.show(), private void cn.itcast.bean.Person.privateMethod(), public static void cn.itcast.bean.Person.staticMethod()] ----------------------------3----------------------------- 私有方法:null 有参方法,参数为:1989 ----------------------------4----------------------------- 公共方法 有参方法,参数为:2016 有参方法,参数为:50 [public cn.itcast.bean.Person(), public cn.itcast.bean.Person(java.lang.String,int)] [private cn.itcast.bean.Person(int), public cn.itcast.bean.Person(), public cn.itcast.bean.Person(java.lang.String,int)]
时间: 2024-11-05 04:08:57