• java反射调用方法


    最近的开发,遇到一个调用其他工程类方法的问题,用到一个简单的方法--java反射。利用反射机制,获取类实例,再获取相应方法,最后执行,得到结果。

    具体应用为:

    Class<?> CIRWindowsAPI = Class.forName("com.fujitsu.ci.runtime.common.CIRWindowsAPI");        
    Method isUNCPath = CIRWindowsAPI.getDeclaredMethod("isUNCPath", String.class);
    Object result = isUNCPath.invoke(null, f.getPath());
    return Boolean.valueOf(result.toString());

    关于java反射还不了解,于是上网搜索相关内容,整理如下:

    1.Class类

    在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例。

    由于Class类没有构造方法,所以实例化Class类的方式有点特殊,有三种方式:

    • 对象.getClass( )
    • 类.Class
    • forName( )
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Test {
       
    }
     
    public class Demo {
        public static void main(String[] args) {
            //方式一:
            Test t = new Test();
            Class<? extends Test> c1 = t.getClass();
            System.out.println(c1);
           
            //方式二:
            //为了避免特殊性,这里不用Test类,而用java库中的String类
            Class<String> c2 = String.class;
            System.out.println(c2);
           
            //方式三:
            //forName()方法会抛出异常
            Class<?> c3 = null;
            try {
                c3 = Class.forName("Test");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.out.println(c3);
        }
    }

    其中,forName( )方法需要重点掌握,因为它可以在类不确定的情况下实例化Class,更具灵活性

    2.Class类的应用

    获取类的结构

    要通过反射获取类的结构我们这里要导入一个新的包java.lang.reflect

    实例a:取得类的构造方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import java.lang.reflect.Constructor;
    import java.util.Arrays;
     
    public class Demo {
        //下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了
        public static void main(String[] args) throws Exception {
            Class<?> c = null;
            try {
                c = Class.forName("java.lang.Boolean");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            //这里的getConstructors()方法返回的是一个Constructor数组
            Constructor<?>[] cons = c.getConstructors();
            //打印的方式你可以自己写,为了方便我用Arrays.toString(),凑合着看
            System.out.println(Arrays.toString(cons));
        }
    }

    实例b:取得类所实现的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import java.util.Arrays;
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Class<?> c = null;
            try {
                c = Class.forName("java.lang.Boolean");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Class<?>[] in = c.getInterfaces();
            System.out.println(Arrays.toString(in));
        }
    }

    实例c:取得父类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Demo {
        public static void main(String[] args) throws Exception {
            Class<?> c = null;
            try {
                c = Class.forName("java.lang.Boolean");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            //注意了,这里不会是数组,why?
            Class<?> su = c.getSuperclass();
            System.out.println(su);
        }
    }

    别忘了,java中是单继承,父类只有一个

    实例d:取得类的全部方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import java.lang.reflect.Method;
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Class<?> c = null;
            try {
                c = Class.forName("java.lang.Boolean");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Method[] m = c.getMethods();
            //好吧,这次我就大发慈悲的写个打印列表出来
            for (int i = 0; i < m.length; i++) {
                System.out.println(m[i]);
            }
        }
    }

    实例e:取得本类的全部属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import java.lang.reflect.Field;
     
    class Person {
        private String name;
        private int age;
    }
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Class<?> c = null;
            try {
                c = Class.forName("Person");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Field[] f = c.getDeclaredFields();
            for (int i = 0; i < f.length; i++) {
                System.out.println(f[i]);
            }
        }
    }

    getDeclaredFielsd()方法可以获取全部属性,getFields()只能获取公共属性

    实例f:获取本类中属性的值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import java.lang.reflect.Field;
     
    class Person {
        public String name;
        private int age;
       
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Person p = new Person("zhangsan",12);
     
            Class<?> c = p.getClass();
           
            //获取公共属性的值
            Field f1 = c.getField("name");
            //get(p)表明要获取是哪个对象的值
            String str = (String) f1.get(p);
            System.out.println("姓名: " + str);
           
            //获取私有属性的值
            Field f2 = c.getDeclaredField("age");
            //age是私有属性,所以要设置安全检查为true
            f2.setAccessible(true);
            int age = (int) f2.get(p);
            System.out.println("年龄: " + age);
        }
    }

    要注意的是:setAccessible()方法可以设置是否访问和修改私有属性

    3.

    反射的应用

    实例g:通过反射修改属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    import java.lang.reflect.Field;
     
    class Person {
        private String name;
       
        public Person(String name) {
            this.name = name;
        }
       
        public String toString() {
            return "姓名: " + this.name;
        }
    }
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Person p = new Person("王二狗");
            System.out.println(p);
            Class<?> c = p.getClass();
       
            //定义要修改的属性
            Field f = c.getDeclaredField("name");
            f.setAccessible(true);
            //修改属性,传入要设置的对象和值
            f.set(p, "张二蛋");
            System.out.println(p);
        }
    }

    几个方法都是有联系的,如果看不懂就先熟悉上面几个例子

    实例h:通过反射调用方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import java.lang.reflect.Method;
     
    class Person {
        public void print(int i) {
            System.out.println("我在写数字: " + i);
        }
       
        public static void say(String str) {
            System.out.println("我在说: " + str);
        }
    }
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            Person p = new Person();
            Class<?> c = p.getClass();
       
            //getMethod()方法需要传入方法名,和参数类型
            Method m1 = c.getMethod("print", int.class);
            //invoke()表示调用的意思,需要传入对象和参数
            m1.invoke(p, 10);
           
            Method m2 = c.getMethod("say", String.class);
            //这里的null表示不由对象调用,也就是静态方法
            m2.invoke(null, "你妹");
        }
    }

    这里演示了一个普通的有参方法和一个静态方法

    既然有参数的都写出来了,那么无参的就更简单了,直接传入一个对象即可

    实例i:通过反射操作数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import java.lang.reflect.Array;
     
    public class Demo {
        public static void main(String[] args) throws Exception {
            int[] arr = {1,2,3,4,5};
            Class<?> c = arr.getClass().getComponentType();
           
            System.out.println("数组类型: " + c.getName());
            int len = Array.getLength(arr);
            System.out.println("数组长度: " + len);
            System.out.print("遍历数组: ");
            for (int i = 0; i < len; i++) {
                System.out.print(Array.get(arr, i) + " ");
            }
            System.out.println();
            //修改数组
            System.out.println("修改前的第一个元素: " + Array.get(arr, 0));
            Array.set(arr, 0, 3);
            System.out.println("修改后的第一个元素: " + Array.get(arr, 0));
        }
    }

    这里要注意一点,getComponentType( )返回的是数组元素的Class。

    以上是初级的理解,更多用法还需继续学习。

    原文请参考:http://www.cnblogs.com/nerxious/archive/2012/12/24/2829446.html

  • 相关阅读:
    C# lock
    read appSettings in configuration file by XElement with xmlns
    get all sites under IIS
    Cross-site scripting(XSS)
    Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code
    C++ 算法
    C++ 数据结构概念
    C++ STL 常用算术和生成算法
    C++ STL 常用拷贝和替换算法
    C++ STL 常用排序算法
  • 原文地址:https://www.cnblogs.com/xiaxiaoxuan/p/4242137.html
Copyright © 2020-2023  润新知