反射

1)定义:就是把JAVA类中的各种成分映射成一个个的java对象。
                         利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。
        2)外存中的类加载到内存中,会形成该对象的Class类。如:String.class、Person.class
                得到此class类的三种方式:
                    1》类.class
                    2》对象.getClass()
                    3》类.forName(String className) //className:包含包的类名
                    eg:
                        String str = "str";
                        Class c1 = String.class;
                        Class c2 = str.getClass();
                
                        Class c3 = Class.forName("java.lang.String");
            
        3)使用不同的方式得到的.class对象在相同的内存空间。
        4)取得构造函数的对象的两种方法:
            1》通过getConstructor(Class... parameterTypes)方法
                    此方法不能获取private的构造函数对象。
                    eg:
                        Constructor con = clazz.getConstructor(null);//null为构造函数的参数,没有就写null
                        
                        Constructor con = clazz.getConstructor(String.class, int.class);
                        Person p = (Person) con.newInstance("berry", 10);
            2》通过getDeclaredConstructor(Class... parameterTypes)和setAccessible(boolean b)方法:
                    此方法也不能取得public的构造函数对象,但可以在后面通过setAccessible(true)方法设置
                    eg:
                        Constructor con = clazz.getDeclaredConstructor(null);
                        
                        //设置非public成员的访问性,默认false不能访问
                        con.setAccessible(true);
                        Person p = (Person) con.newInstance(null);
        5)取得字段对象
            1》通过Class对象的getField("字段名字");或者getDeclaredField("字段名称")获取字段对象
            2》通过Field对象的set(对象名, "此对象的字段值");设置字段值
                eg:
                    Field f = clazz.getDeclaredField("name");
                    f.setAccessible(true);
                    
                    Person p = new Person();
                    f.set(p, "杰克");//相当于:p.setName("杰克")
                    System.out.println("用户名:"+p.getName());//用户名:杰克
     6)获取方法对象
             1》通过getMethod("方法名",Class... parameterTypes);
                     或者
                     getDeclaredMethod("方法名" , Class... paramterTypes);
                     获取Method对象。
             2》通过invoke(Object obj, Object... args)方法调用此方法
                 【静态函数,对象引用可以为null;
                     没有参数,形参值为null】
                eg1:
                    Method m = clazz.getMethod("show", String[].class, double.class);    
                    m.invoke(p, new String[]{"sing", "dance"}, 5000);
            3》获得函数返回值:
                     invoke(Object obj, Object... args)的返回值就是函数对象的返回值
                         
     7)获取main函数对象【特例】
             !注意:在反射main方法时,编译器会将数组自动拆分,取第一个值
             
                 Method m = c.getMethod("main", String[].class);
                //静态方法不需要对象
                //m.invoke(null, new String[]{"A", "B", "C"});//抛出异常:要求传入的是一个数组对象,而其传入的是一个字符串"A".
                
                //解决办法一:将数组强制转换成一个对象
                m.invoke(null, (Object)new String[]{"A", "B", "C"});
                //解决办法二:将错就错,在数组中的嵌套一个数组。
                m.invoke(null, new Object[]{new String[]{"A", "B", "C"}});
        总结:
            /*获得私有的构造函数对象:
                    通过getConstructor会出现异常:java.lang.NoSuchMethodException: cn.itcast.java.reflect.Person.<init>()
                    通过getDeclaredConstructor也会出现异常:java.lang.IllegalAccessException: Class cn.itcast.java.reflect.Demo4 can not access a member of class cn.itcast.java.reflect.Person with modifiers "private"
            */
                        
        

 

posted on 2014-09-03 12:46  SkyGood  阅读(190)  评论(0编辑  收藏  举报