反射

来源:互联网 发布:artrage mac破解 编辑:程序博客网 时间:2024/05/18 03:30

我所理解的反射
根据一个已经实例化了的对象来还原类的完整信息
反射的定义
JAVA反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取以及动态调用对象的方法的功能成为java语言的反射机制。
(在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例)
1.获取类(类的实例化)
(1)对象.getclass()
(2)类.class
(3)Class.forName()
(1)(2)(3)得到的是类类型,通过类类型可以获取该类的各种信息
2.创建对象
Class类中有一个方法叫做newInstance( ),它可以用来创建一个Class类对象的新实例

3.代码实例
实例化

package com.imooc.reflect;public class CalssDemo1 {    public static void main(String[] args){        // TODO Auto-generated method stub        Foo foo1=new Foo();        //Foo这个类也是一个实例对象,Class类的实例对象        //任何一个类都是class的实例对象,有三种表示方式        //1.任何一个类都有一个隐含的成员变量class        Class c1=Foo.class;        //2.已知该类的对象,通过getClass()方法        Class c2=foo1.getClass();        //c1 c2表示了Foo类的类类型(class type)        //3.        Class c3=null;        try {            c3=Class.forName("com.imooc.reflect.Foo");        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        //c1 c2 c3肯定是相等的,因为她们都代表了Foo类的类类型        System.out.println(c1==c2);        System.out.println(c2==c3);        //通过类的类类型创建该类的对象实例,需要有无参数的构造方法        //通过类类型可以获得该类的很多信息,什么方法属性之类的!!        try {            Foo foo=(Foo)c1.newInstance();            foo.print();        } catch (InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalAccessException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }   }class Foo{    void print() {        System.out.println("first!");    }}

获取类的信息 包括类的成员函数 成员变量

package com.imooc.Demo2;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ClassUtil {    /*         打印类的信息,包括类的成员函数,成员变量     */    public static void printFieldMessage(Object obj) {         //获取类的信息,首先获取类的类型,有三种方式,使用第二种        Class c=obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型        System.out.println("类的名称是:"+c.getName());        /*          1.Method类,方法对象          2.一个成员方法就是一个Method对象          3.getMethods()方法获取的是所以的public的函数,包括父类继承而来的          3.getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限         */           Method[] ms=c.getMethods();           for(int i=0;i<ms.length;i++) {               //得到方法的返回值类型的类类型               Class returnType=ms[i].getReturnType();               System.out.print(returnType.getName()+" ");               //得到方法的名称               System.out.println(ms[i].getName()+",");               //获取参数类型-->得到的是参数列表的类型的类类型               Class[] paramTypes=ms[i].getParameterTypes();               for(Class class1:paramTypes) {                   System.out.println(class1.getName()+",");               }               /*                1.成员变量也是对象                2.java.lang.reflect.Field                3.Field类封装了关于成员变量的操作                4.getFields()方法获取的是所以public的成员变量的信息                5.getDeclaredFields获取的是该类自己声明的成员变量的信息                */                Field[] fs=c.getDeclaredFields();                for(Field field:fs) {                    //得到成员变量的类型的类类型                    Class fieldType=field.getType();                    String typeName=fieldType.getName();                    //得到成员变量的名称                    String fieldName=field.getName();                    System.out.println(typeName+" "+fieldName);                }           }        }    }

方法反射的基本操作

package com.imooc.Demo2;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class MethodDemo1 {    public static void main(String[] args)            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {        // TODO Auto-generated method stub        // 获取print(int,int)方法,即获取类的信息,获取类的类类型        A a1 = new A();        Class c = a1.getClass();        /*         * 2.获取方法 名称和参数列表来决定 getMethod获取的是        public的方法 getDeclaredMethod自己声明的方法         */        try {            //int.class与string.class是方法对象            Method m = c.getMethod("print", int.class, int.class);            // 方法的反射操作            // a1.print(10, 20);方法的反射操作是用m对象来进行方法          调用,和a1.print相同            //方法如果没有返回值返回null,如果有返回值返回具体的返回值            Object o = m.invoke(a1, 10,20);            System.out.println("------------------");            //获取方法print(string,string)            Method m1=c.getMethod("print", String.class,String.class);            o=m1.invoke(a1, "hello","world");        } catch (NoSuchMethodException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (SecurityException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}class A {    public void print(int a, int b) {        System.out.println(a + b);    }    public void print(String a, String b) {        System.out.println(a.toUpperCase() + "," + b.toLowerCase());    }}

通过反射了解集合泛型的本质

package com.imooc.Demo2;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;public class MethodDemo4 {    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {        // TODO Auto-generated method stub        ArrayList list=new ArrayList();        ArrayList<String> list1=new ArrayList<String>();        list1.add("hello");        //list1.add(2)错误        Class c1=list.getClass();        Class c2=list1.getClass();        System.out.println(c1==c2);        //反射的操作都是编译之后的操作        /*         * c1==c2为true说明编译之后集合的泛型是去泛型化的         * java中集合的泛型,是防止错误输入的,只在编译阶段有效         * 绕过编译就无效了         */        try {            Method m=c2.getMethod("add", Object.class);            m.invoke(list1, 20);//绕过编译操作就绕过了泛型            System.out.println(list1.size());            System.out.println(list1);//foreach遍历就抛出异常        } catch (NoSuchMethodException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (SecurityException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
原创粉丝点击