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()
原文地址:https://www.cnblogs.com/wsyblog/p/7469720.html