1 反射

作者: 一枝妖孽 | 来源:发表于2018-06-04 21:34 被阅读0次

    1、什么是反射?
    反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

    2、Class类
    要利用反射,必须先得到代表字节码的Class。Class类用于表示.class文件(字节码)。

    如何得到某个class文件对应的class对象。
    1)类名.class,
    2)对象.getClass()
    3)Class.forName(“类名”)
    4)基本类型的包装类.TYPE
    总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int,void…

    3、解剖类
    Class对象提供了如下常用方法:

    public Constructor getConstructor(Class<?>…parameterTypes)
    public Method getMethod(String name,Class<?>… parameterTypes)
    public Field getField(String name) 
    
    public Constructor getDeclaredConstructor(Class<?>…parameterTypes)
    public Method getDeclaredMethod(String name,Class<?>… parameterTypes)
    public Field getDeclaredField(String name)
    

    这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、Method、Field对象表示。

    4、利用Constructor创建对象
    Constructor类提供了如下方法,用于创建类的对象:

    public Object newInstance(Object…initargs)
    

    initargs用于指定构造函数接收的参数

    Constructor可以反射类无参、有参、私有的构造函数,创建类的对象

    Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
    String obj = (String)Class.forName("java.lang.String").newInstance()

    5、利用Method调用方法
    Method提供了如下方法,用于执行它所代表的方法

    public Object invoke(Object obj,Object…args)
    

    使用Method可以分别执行无参、有参、多参(带数组和基本数据类型)、静态、私有的方法

    6、Field类
    Field类代表某个类中的一个成员变量

    f.get();
    f.set();
    

    包含私有变量、静态变量、公共变量

    7、反射main方法
    问题:
    启动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的语法解释,因此会出现参数类型不对的问题。
    解决办法:

    mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
    mainMethod.invoke(null,(Object)new String[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了
    

    0 Person类

    public class Person {
        public String name="demoName";
        private int age = 18;
        public static Date time;
        
        public int getAge() {
            return age;
        }
        public Person(){
            System.out.println("默认构造方法执行了");
        }
        public Person(String name){
            System.out.println("姓名:"+name);
        }
        public Person(String name,int age){
            System.out.println(name+"="+age);
        }
        private Person(int age){
            System.out.println("年龄:"+age);
        }
        
        public void m1(){
            System.out.println("m1");
        }
        public void m2(String name){
            System.out.println(name);
        }
        public String m3(String name,int age){
            System.out.println(name+":"+age);
            return name+":"+age;
        }
        private void m4(Date d){
            System.out.println(d);
        }
        public static void m5(){
            System.out.println("m5");
        }
        private static void m6(String[] strs){
            System.out.println(strs.length);
        }
        public static void main(String[] args) {
            System.out.println("main");
        }
    }
    

    1 反射构造

    public class Demo1 {
        //反射:public Person()
        @Test
        public void test1() throws Exception{
            //得到字节码
            Class clazz = Class.forName("cn.demo.base.reflect.Person");//代表Person类在内存中的字节码对象
    //      Class clazz = p.getClass();
    //      Class clazz = Person.class;
            Constructor c = clazz.getConstructor(null);//得到构造方法干嘛?创建对象
            c.newInstance(null);
            
        }
        @Test
        public void test11() throws Exception{
            Class clazz = Class.forName("cn.demo.base.reflect.Person");
            Person p = (Person)clazz.newInstance();//调用默认的构造方法
            System.out.println(p.name);
        }
        //反射:public Person(String name)
        @Test
        public void test2() throws Exception{
            //得到字节码
            Class clazz = Class.forName("cn.demo.base.reflect.Person");//代表Person类在内存中的字节码对象
            Constructor c = clazz.getConstructor(String.class);
            c.newInstance("朱巧玲");
            
        }
        @Test//public Person(String name,int age)
        public void test3() throws Exception{
            Class clazz = Class.forName("cn.demo.base.reflect.Person");
            Constructor c = clazz.getConstructor(String.class,int.class);
            Person p = (Person)c.newInstance("朱朱",20);
            System.out.println(p.name);
            
        }
        @Test//private Person(int age)
        public void test4() throws Exception{
            Class clazz = Class.forName("cn.demo.base.reflect.Person");
            Constructor c = clazz.getDeclaredConstructor(int.class);//读取私有的构造方法的
            c.setAccessible(true);//暴力反射
            Person p = (Person)c.newInstance(20);
            System.out.println(p.name);
            
        }
        @Test//类中的所有构造方法
        public void test5() throws Exception{
            Class clazz = Class.forName("cn.demo.base.reflect.Person");
            Constructor[]  cs = clazz.getDeclaredConstructors();
            System.out.println(cs.length);
            
        }
    }
    

    2 反射类中的方法

    public class Demo2 {
        //public void m1()
        @Test
        public void test1() throws Exception{
            Class clazz = Person.class;
            Person p = (Person) clazz.newInstance();
            Method m = clazz.getMethod("m1", null);//得到方法干嘛?
            m.invoke(p, null);
        }
        @Test//public void m2(String name)
        public void test2() throws Exception{
            Class clazz = Person.class;
            Person p = (Person) clazz.newInstance();
            Method m = clazz.getMethod("m2", String.class);//得到方法干嘛?
            m.invoke(p, "葛付以");
        }
        @Test//public String m3(String name,int age)
        public void test3() throws Exception{
            Class clazz = Person.class;
            Person p = (Person) clazz.newInstance();
            Method m = clazz.getMethod("m3", String.class,int.class);//得到方法干嘛?
            String returnValue = (String)m.invoke(p, "葛付以",23);
            System.out.println(returnValue);
        }
        @Test//private void m4(Date d)
        public void test4() throws Exception{
            Class clazz = Person.class;
            Person p = (Person) clazz.newInstance();
            Method m = clazz.getDeclaredMethod("m4", Date.class);//得到方法干嘛?
            m.setAccessible(true);
            m.invoke(p,new Date());
        }
        @Test//public static void m5()
        public void test5() throws Exception{
            Class clazz = Person.class;
            Method m = clazz.getMethod("m5", null);//得到方法干嘛?
            m.invoke(null,null);
        }
        @Test//private static void m6(String[] strs)
        public void test6() throws Exception{
            Class clazz = Person.class;
            Method m = clazz.getDeclaredMethod("m6",String[].class);//得到方法干嘛?
            m.setAccessible(true);
            m.invoke(null,(Object)new String[]{"a","b"});
        }
        @Test
        public void test7() throws Exception{
            Class clazz = Person.class;
            Method m = clazz.getMethod("main",String[].class);//得到方法干嘛?
            m.invoke(null,new Object[]{new String[]{"a","b"}});
        }
    }
    

    3 反射字段:Field

    public class Demo3 {
        
        @Test
        public void test1() throws Exception{
            Class clazz = Person.class;
            Person p = (Person)clazz.newInstance();
            Field f = clazz.getField("name");
            String s = (String)f.get(p);
            System.out.println(s);
            
            //更改name的值
            f.set(p, "上海");
            System.out.println(p.name);
        }
        @Test//private int age = 18;
        public void test2() throws Exception{
            Class clazz = Person.class;
            Person p = (Person)clazz.newInstance();
            Field f = clazz.getDeclaredField("age");
            f.setAccessible(true);
            int age = (Integer)f.get(p);
            System.out.println(age);
            
            f.set(p, 28);
            age = (Integer)f.get(p);
            System.out.println(age);
        }
        @Test//public static Date time;
        public void test3() throws Exception{
            Class clazz = Person.class;
            Field f = clazz.getField("time");
            f.set(null, new Date());
            System.out.println(Person.time);
        }
    }
    

    相关文章

      网友评论

          本文标题:1 反射

          本文链接:https://www.haomeiwen.com/subject/htxusftx.html