• java反射机制


    在运行期间动态的获取类的信息以及动态调用类的方法就是java的反射机制。

    在运行时判断任意对象所属的类,运行是构造一个类,运行时判断一个类的方法和属性,运行时调用一个类的方法。

    运行时判断一个类的方法和属性实例:

    import java.lang.reflect.Method;

    public class Test01 {

        public static void main(String[] args) throws Exception {
            //获取指定名字的class对象第一方法
            //Class<?> classType = Class.forName("java.lang.String");
            //第二种方法
            Class<?> classType = java.lang.String.class;
            //获取公用的方法public
            //Method[] methods = classType.getMethods();
            //获取所有声明的方法包括public,protected,private
            Method[] methods = classType.getDeclaredMethods();
            for(Method m : methods){
                System.out.println(m);
            }
        }
    }

    运行时调用一个类的方法实例:

    import java.lang.reflect.Method;

    public class Test02newInstance {

        public int add(int p1, int p2){
            return p1 + p2;
        }
        
        public String echo(String param){
            return param;
        }
        
        public static void main(String[] args) throws Exception {
            Class<?> classType = Test02newInstance.class;
            //通过类的对象的newInstance()方法来创建类的实例相当于new Test02newInstance()
            Object tnt = classType.newInstance();
            //System.out.println(tnt instanceof Test02newInstance);
            //使用类的对象而不是实例对象来获取类的方法对象,传入方法名和方法的参数
            Method m = classType.getMethod("add", new Class[]{int.class, int.class});
            //通过方法对象的invoke()方法来调用类里面的方法,第一个参数为类的实例对象,第二个参数为方法对象的参数
            System.out.println(m.invoke(tnt, new Integer[]{1,5}));
            System.out.println("----------");
            
            Method m1 = classType.getMethod("echo", new Class[]{String.class});
            System.out.println(m1.invoke(tnt, new String[]{"tom"}));
        }
    }
    对象拷贝:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    public class Test03 {

        public static Object copy(Object srcObj) throws Exception{
            //获取class 对象,使用对象获取
            Class<?> classType = srcObj.getClass();
            
            //下面两行代码先通过类的class对象获得其构造方法,可传递参数
            //然后通过该构造方法对象的newInstance()方法来创建一个类的实例
            //该方法可调用不带参数的构造方法或者带参数的构造方法来生成对象
            //通过new Class[]{}来传递参数
            Constructor cons = classType.getConstructor(new Class[]{});
            Object destObj = cons.newInstance(new Object[]{});
            //上面两行可写成
            //Object o2 = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
            //System.out.println(cons);
            //System.out.println(o1);
            //System.out.println(classType);
            //System.out.println(classType.getName());
            
            //获取成员变量
            Field[] fields = classType.getDeclaredFields();
            System.out.print("scource:");
            for(Field field : fields){
                String fName = field.getName();
                String setMethName ="set" + fName.substring(0, 1).toUpperCase() + fName.substring(1);
                String getMethName ="get" + fName.substring(0, 1).toUpperCase() + fName.substring(1);
                
                //获取class对象中的get和set方法对象
                Method setMethod = classType.getMethod(setMethName, new Class[]{field.getType()});
                Method getMethod = classType.getMethod(getMethName, new Class[]{});
                
                //源对象和目标对象同属于一个class对象
                //获取源对象中的成员变量的值
                Object value = getMethod.invoke(srcObj, new Object[]{});
                System.out.print(value + ",");
                //将源对象中的成员变量的值设置到目标对象中
                setMethod.invoke(destObj, new Object[]{value});
                
            }
            System.out.println();
            return destObj;
        }
        
        public static void main(String[] args) throws Exception {
            Customer custsrc = new Customer(1l,"zs", 23);
            Customer custdest = (Customer)copy(custsrc);
            System.out.println("destination:"+custdest.getId() + "," + custdest.getName() + "," + custdest.getAge());
            
            
        }
        
    }

    class Customer {
        private Long id;
        private String name;
        private int age;
        public Customer() {
            super();
        }
        public Customer(Long id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
    }

  • 相关阅读:
    模仿微信右上角菜单栏
    改变checkbox的默认样式
    webpack中的静态资源处理
    如何解决Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]
    页面生命周期
    关于在使用Exchange2003系统时无法向sina,yahoo,hotmail等邮箱发送邮件问题的解决方法
    重置TCP/IP协议堆栈的经历
    网通电信双线路上网,网通的走网通线路,电信的走电信线路,内网通过NAT上网,双线路故障自动切换
    在OUTLOOK或OWA中查看邮件的SCL级别(转)
    常用的RBL服务器列表及介绍
  • 原文地址:https://www.cnblogs.com/charleszhang1988/p/javaReflect.html
Copyright © 2020-2023  润新知