黑马程序员_java的反射机制

来源:互联网 发布:忘尘娇喘 网络歌手 编辑:程序博客网 时间:2024/05/17 08:42
黑马程序员_java反射机制
------android培训、java培训、期待与您交流!------

什么是反射:反射其实就加载类解剖类的组成部分。
通常在写框架时,就需要使用大量的反射技术来完成一些操作。
在java中如何来使用反射技术?
1.获取此类的字节码对象。可以通过java中最常见的三种方式获取。
(1)Class.forName("类的完整路径");//就是包名加类名
(2)类名.class
(3)对象名.getClass();
2.解剖里面类中的组成部分,分别是(成员变量,成员函数,构造函数)。
同过Class类中的一些方法可以实现,分别是:
getFields()//获取此类的所有public修饰的字段getMethods();获取此类的所有public修饰的函数getConstructors();//获取此类所有被public修饰的构造函数getField(name)//获取此类被public修饰名为name的字段getMethod(name,Types)//获取此类被public修饰名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型getConstructor(Types)//根据Types参数获取此类被public修饰的构造函数,Types是可变参数类型。----------------------------------------------getDeclaredFields()//获取此类所有的字段,也包含私有的。getDeclaredMethods();获取此类的所有的函数,也包含私有的getDeclaredConstructors();获取此类的所有的构造函数,也包含私有的getDeclaredField(name)//获取此类中为名name的字段,也包含私有的getDeclaredMethod(name,Types)//获取此类的名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型,也包含私有的。


getDeclaredConstructor(Types)//根据Types参数获取此类的构造函数,Types是可变参数类型,也包含私有的。
(1)(通过反射获取字段,并使用)
package Test;import java.lang.reflect.Field;
class Person{public String name;}public class Demo1 {public static void main(String[] args)throws Exception{Class clazz=Class.forName("Test.Person");//获得Person类字节码对象Person p=new Person();Field fieName=clazz.getField("name");String str=(String)fieName.get(p);//获取p对象中的name字段的值}}
(2)(通过反射获取成员函数,并调用)
package Test;import java.lang.reflect.Method;class Person{public void show(){System.out.println("我是无参show方法");}public void show(String name){System.out.println("我是有参"+name);}}public class Demo1 {public static void main(String[] args)throws Exception{Class clazz=Class.forName("Test.Person");//获得Person类字节码对象Person p=new Person();Method metShow=clazz.getMethod("show",null);//获取无参show方法,没参所以传nullMethod metShow2=clazz.getMethod("show",String.class);//获取有参show方法。metShow.invoke(p,null);//用p对象调用此方法metShow2.invoke(p,"show方法");}}
(3)(通过反射获取构造函数,并创建对象)
package Test;import java.lang.reflect.Constructor;class Person{public Person(){System.out.println("调用无参构造函数创建对象");}public Person(int age,String name){System.out.println("调用有参构造函数创建对象");}}public class Demo1 {public static void main(String[] args)throws Exception{Class clazz=Class.forName("Test.Person");//获得Person类字节码对象Constructor constru1=clazz.getConstructor(null);//获取此类的无参构造函数Constructor constru2=clazz.getConstructor(int.class,String.class);//获取此类多参的构造函数constru1.newInstance(null);//调用无参构造函数创建对象constru2.newInstance(34,"黑马_小爻");//调用多参构造函数创建对象}}

如果是非public修饰的成员如何获取并使用呢?
我就举一个例子,因为其他的都一样
案例(获取非public修饰的成员的函数并调用)
package Test;import java.lang.reflect.Method;class Person{private void show(){System.out.println("我来了,黑马!!");}}public class Demo1 {public static void main(String[] args)throws Exception{Class clazz=Class.forName("Test.Person");Person p=new Person();Method method=clazz.getDeclaredMethod("show",null);//由show方法时private的,所以只能通过getDeclaredMethod方法才能获得method.setAccessible(true);//这里为true代表java使用它时不对其进行访问权限语法检查method.invoke(p,null);}}

有一件事情值得注意,如果方法的参数为数组类型,通过反射获取此方法时一定要记得将数组强转为Object
如:通过反射获取main方法。
package Test;import java.lang.reflect.Method;class Person{public static void main(String[] args){System.out.println("Person");}public static void show(Object[] obj){System.out.println(obj.length);}}public class Demo1 {public static void main(String[] args)throws Exception{Class clazz=Class.forName("Test.Person");Method met=clazz.getMethod("main",String[].class);met.invoke(null,(Object)new String[]{"你好黑马"});/*为什么要将String数组强转为Object对象呢? * 这是java升级后遗留下来的问题,因为在java1.4版本的时候,还没有可变参数类型时,我们这里参数类型是一个Object[]数组 * 我们把Object数组中的每个角标元素来出来当方法参数。来确定我们要获取的方法 * 1.5有了可变参数后,java为了使旧版本能够兼容新版本,所以只要你传数组,还是按老办法获取方法 * 所以上面的运行实际是把数组拆开后把其中的元素传进去的,并不是把String数组传进去的。 * */}}

邮箱:wolaoben7252@qq.com