• Java反射


      这几天又重新学习了一下反射,略有感悟(以下是学习笔记):

    镜像:类被加载到内存以后,通过类镜像来表示,java.lang.Class
    反射:在运行时,通过类镜像进行类操作(获取类信息、构建类对象、调用方法等),使用java.lang.reflect包下的API(Field、Method、Constructor)

    反射使用场景:当类的信息在编译时无法确定,运行时才能确定下来时,必须使用反射进行相关操作

    反射编程步骤:
    1)获取类镜像:java.lang.Class.forName(...)
    2)如需要,创建类实例对象:Class-->newInstance()
    3)调用反射相关API:
    java.lang.reflect.Field
    java.lang.reflect.Constructor
    java.lang.reflect.Method

      以下是一个当你不知道客户所用数据库类型时,依靠反射来获取类镜像的过程:

    //这是db.cfg文件,要从中获取类名与方法名
    driver=com.wsy.refluction.OracleDriver
    method=load
    
    //以下是Java程序
    package com.wsy.refluction;
    
    import java.io.FileInputStream;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    interface Driver{
        public void load(String info , String name);
    }
    
    class OracleDriver implements Driver{
    
        @Override
        public void load(String info , String name) {
            System.out.println("This is OracleDriver " + "info:" + info + " " + "name:" + name);
        }
        
    }
    
    class MySQLDriver implements Driver{
    
        @Override
        public void load(String info , String name) {
            System.out.println("This is MySQLDriver");
        }
        
    }
    
    class SQLServerDriver implements Driver{
    
        @Override
        public void load(String info , String name) {
            System.out.println("This is SQLServerDriver");
        }
        
    }
    public class Refluction {
        public static void main(String[] args) {
            Properties prop = new Properties();
            try {
                prop.load(new FileInputStream("src/com/wsy/refluction/db.cfg"));
                String driverName = prop.getProperty("driver");
                String methodName = prop.getProperty("method");
                //结果:com.wsy.refluction.OracleDriver
                System.out.println(driverName);
                Class<?> c = Class.forName(driverName);
                Object o = c.newInstance();
                //结果:com.wsy.refluction.OracleDriver@15db9742
                System.out.println(o);
                Method[] methods = c.getMethods();
                for(Method method : methods) {
                    if(method.getName().equals(methodName)) {
                        //结果:This is OracleDriver
                        //调用成员方法
                        method.invoke(o , new Object[] {"driver" , c.getName()});
                        //调用静态方法
                        //method.invoke(null , new Object[] {"driver" , c.getName()});
                        
                    }
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

      下面这个程序是通过反射来获取一个类的各种信息:

    //随意定义一个类(这里以Student类为例)
    package com.wsy.refluction;
    
    public class Student implements Comparable<Object>{
        private String name;
        private int age;
        public Student(){}
        public Student(String name,int age){
            this.name = name;
            this.age = age;
        }
        public String getName(){
            return name;
        }
        //public void setName(String name){
        private void setName(String name){
            this.name = name;
        }
        public int getAge(){
            return age;
        }
        public void setAge(){
            this.age = age;
        }
        public String toString(){
            StringBuffer sb = new StringBuffer();
            sb.append("name:");
            sb.append(name);
            sb.append(",age:");
            sb.append(age);
            return sb.toString();
        }
        public boolean equals(Object o){
            if(!(o instanceof Student))
                return false;
            Student s = (Student)o;
            return ((s.name.equals(name)) && (s.age == age));
        }
        public int hashCode(){
            return name.hashCode() + age;
        }
        public int compareTo(Object o){
            Student s = (Student)o;
            return s.age - age;
        }
        public static void talk(){
            System.out.println("in Student talk()");
        }
    }
    
    //以下是主程序
    package com.wsy.refluction;
    
    import java.lang.reflect.*;
    
    public class ReflectionTest2{
        public static void printClass(Class clazz){
            Package pac = clazz.getPackage();
            String pacName = pac.getName();
            System.out.println("package " + pacName + ";");
            int modify = clazz.getModifiers();
            String modifier = Modifier.toString(modify);
            String className = clazz.getName();
            boolean isInterface = clazz.isInterface();
            String classFlag = "";
            if(isInterface)
                classFlag = "interface";
            else
                classFlag = "class";
            System.out.println(modifier + " " + classFlag + " " + className + "{");
        }
        public static void printField(Class clazz){
            Field[] fields = clazz.getDeclaredFields();
            String modifier;
            String type;
            String fieldName;
            for(int i = 0;i < fields.length;i++){
                modifier = Modifier.toString(fields[i].getModifiers());    
                type = fields[i].getType().getName();
                fieldName = fields[i].getName();
                System.out.println("	" + modifier + " " + type + " " + fieldName + ";");
            }
        }
        public static void printConstructor(Class clazz){
            Constructor[] cons = clazz.getDeclaredConstructors();
            String consInfo;
            for(int i = 0;i < cons.length;i++){
                consInfo = cons[i].toGenericString();
                System.out.println("	" + consInfo + "{...}");
            }
        }
        public static void printMethod(Class clazz){
            Method[] methods = clazz.getDeclaredMethods();
            String methodInfo;
            for(int i = 0;i < methods.length;i++){
                methodInfo = methods[i].toGenericString();
                System.out.println("	" + methodInfo + "{...}");
            }
            System.out.println("}");
        }
        public static void main(String[] args)throws Exception{
            if(args.length != 1){
                System.out.println("Please input argument!");
                System.exit(1);
            }
            Class clazz1 = Class.forName(args[0]);
            ClassLoader loader = new ClassLoader(){};
            Class clazz2 = loader.loadClass(args[0]);
            System.out.println("clazz1:" + clazz1);
            System.out.println("clazz2:" + clazz2);
            Student stu = new Student();
            Class clazz3 = stu.getClass();
            Class clazz4 = com.wsy.refluction.Student.class;
            System.out.println("clazz3:" + clazz3);
            System.out.println("clazz4:" + clazz4);
            
            System.out.println("*********************");
            printClass(clazz1);
            printField(clazz1);
            printConstructor(clazz1);
            printMethod(clazz1);
    
            System.out.println("*********************");
            Constructor[] cons = clazz1.getConstructors();
            Constructor con = null;;
            for(int i = 0;i < cons.length;i++){
                if(cons[i].getParameterTypes().length != 2)
                    continue;
                con = cons[i];
            }
            Student s = (Student)con.newInstance(new Object[]{"Jack",20});
            System.out.println("studnet:" + s);
    
            Method[] methods = clazz1.getDeclaredMethods();
            Method method = null;
            Method method2 = null;
            for(int i = 0;i < methods.length;i++){
                if("setName".equals(methods[i].getName())){
                    method = methods[i];
                }
                if("talk".equals(methods[i].getName())){
                    method2 = methods[i];
                }
            }
            // 如果是静态方法,第一个参数传null,如果没有参数,第二个传null
            method.setAccessible(true);
            method.invoke(s, new Object[]{"Tom"});
            System.out.println(s);
            method2.invoke(null,new Object[]{});    
        }
    }
    
    
    //以下是运行结果
    clazz1:class com.wsy.refluction.Student
    clazz2:class com.wsy.refluction.Student
    clazz3:class com.wsy.refluction.Student
    clazz4:class com.wsy.refluction.Student
    *********************
    package com.wsy.refluction;
    public class com.wsy.refluction.Student{
        private java.lang.String name;
        private int age;
        public com.wsy.refluction.Student(){...}
        public com.wsy.refluction.Student(java.lang.String,int){...}
        public boolean com.wsy.refluction.Student.equals(java.lang.Object){...}
        public java.lang.String com.wsy.refluction.Student.toString(){...}
        public int com.wsy.refluction.Student.hashCode(){...}
        public int com.wsy.refluction.Student.compareTo(java.lang.Object){...}
        public java.lang.String com.wsy.refluction.Student.getName(){...}
        private void com.wsy.refluction.Student.setName(java.lang.String){...}
        public static void com.wsy.refluction.Student.talk(){...}
        public void com.wsy.refluction.Student.setAge(){...}
        public int com.wsy.refluction.Student.getAge(){...}
    }
    *********************
    studnet:name:Jack,age:20
    name:Tom,age:20
    in Student talk()
  • 相关阅读:
    国内顺利使用Google的另类技巧
    Java进程间通信
    Java 多线程(七) 线程间的通信——wait及notify方法
    转:关于copy_to_user()和copy_from_user()的一些用法
    转: pthread_detach()函数
    转:pthread_create()
    转: ubuntu配置NFS,挂载开发板
    转:全志A20 GPIO 总结文档
    转:Linux 内核中的 cdev_alloc和cdev_add
    转:1.1 cdev_init cdev_alloc 使用说明
  • 原文地址:https://www.cnblogs.com/wsyblog/p/7469720.html
Copyright © 2020-2023  润新知