反射         反射就是把Java类中的各种成分映射成一个个的java对象。         例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个         对象。可能把它说成解剖更容易理解。  /**     关于Constructor类,其实例对象代表类的一个构造方法。     1、得到某个类所有的构造方法,例:         Constructor [] constructors= Class.forName("java.lang.String").getConstructors();     2、得到某一个构造方法,例:                 Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);     3、利用构造方法创建实例对象:         String str = (String)constructor.newInstance(“abc”);     4、Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。         String obj =(String)Class.forName("java.lang.String").newInstance(); */ //反射构造函数示例:     //反射构造函数    public Person()     @Test     public void test1() throws Exception{         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Constructor    c    =    clazz.getConstructor(null);    //public         Person    p    =    (Person) c.newInstance(null);                 System.out.println(p.name);     }         //另一种方法,等效于上。要求类中必须有无参构造函数     @Test     public void test5() throws Exception{         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Person    p    =    (Person) clazz.newInstance();                 System.out.println(p);     }         //反射构造函数    public Person(String name)     @Test     public void test2() throws Exception{         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Constructor    c    =    clazz.getConstructor(String .class);         Person    p    =    (Person) c.newInstance("xxx");                 System.out.println(p.name);     }         //反射构造函数    private Person(List list)     @Test     public void test4() throws Exception{         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Constructor    c    =    clazz.getDeclaredConstructor(List .class);    //包括private         c.setAccessible(true);    //暴力手段,强制开启访问权限         Person    p    =    (Person) c.newInstance(new ArrayList());                 System.out.println(p.name);     } /**     Field类代表某个类中的一个成员变量     问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?     类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联的是哪个对象呢?     所以字段fieldX 代表的是x的定义,而不是具体的x变量。(注意访问权限的问题)     例:         //Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getField("x");         Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");         x.setAccessible(true); */    //反射字段示例:        //反射字段    public String name    =    "aaa";     @Test     public void test1() throws Exception{                Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Field f    =    clazz.getField("name");         //获取字段的值         Object value    =    f.get(p);                 //获取字段的类型         Type    type    =    f.getType();                 //判断字段         if (type.equals(String .class)) {             String svalue    =    (String) value;             System.out.println(svalue);         }                 //设置字段的值         f.set(p, "bbb");         System.out.println(p.name);     }         //反射字段        private int    password    =    123;     @Test     public void test2() throws Exception{                Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Field f    =    clazz.getDeclaredField("password");    //private         //暴力打开权限         f.setAccessible(true);         //获取字段的值         Integer    pwd    =     (Integer) f.get(p);         System.out.println(pwd);             }     /**     关于Method类,其代表某个类中的一个成员方法     1、得到类中的某一个方法:         例子:         Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);     2、调用方法:         ·通常方式:System.out.println(str.charAt(1));         ·反射方式: System.out.println(charAt.invoke(str, 1));         注意:如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的必定是一个静态方法!     3、jdk1.4和jdk1.5的invoke方法的区别:         Jdk1.5:public Object invoke(Object obj,Object... args)         Jdk1.4:public Object invoke(Object obj,Object[] args),                 即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,                 所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。    */    //反射方法示例:     //反射方法    public void m()     @Test     public void test1() throws Exception{                Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Method    method    =    clazz.getMethod("m", null);         method.invoke(p, null);     }         //反射方法    public Class[] m(String name,int[] password)     @Test     public void test3() throws Exception{                Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Method    method    =    clazz.getMethod("m", String .class,int[] .class);         method.invoke(p, "ok",new int[]{1,2,3});     }         //反射方法(私有)    private    void m(FileInputStream in)     @Test     public void test4() throws Exception{                Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Method    method    =    clazz.getDeclaredMethod("m", FileInputStream .class);         method.setAccessible(true);         method.invoke(p, new FileInputStream("D:a.txt"));     }         //反射方法(静态)    public static void m(int num)     @Test     public void test5() throws Exception{                //Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Method    method    =    clazz.getDeclaredMethod("m", int .class);         method.invoke(null, 1);        //静态方法可以直接调用,故不需要再new出一个Person对象     }     /**     最后要注意用反射方式执行某个类中的main方法     1、目标:         写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。用普通方式调完后,大家要明白为什么要用反射方式去调啊?     2、问题:         启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),         通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?         按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,         当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?         jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。         所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),         javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。     3、解决办法:         mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});         mainMethod.invoke(null,(Object)new String[]{"xxx"}); //编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了 */ //反射main函数示例: //反射main函数    public static void main(String[] args)     @Test     public void test6() throws Exception{                //Person    p    =    new    Person();         Class    clazz    =    Class.forName("he.junhua.reflect.Person");         Method    method    =    clazz.getDeclaredMethod("main", String[] .class);         method.invoke(null,(Object)new String[]{"aa","bb"});                //method.invoke(null,new Object[]{new String[]{"aa","bb"}});            }