java反射

  反射是java一个非常强大的功能,在实际业务开发中基本不会用到,但是在框架和一些工具中确实用的很多。

  反射的主要特点就是通过已知的一些信息来获取Class对象,通过Class对象来进一步获取类的基本信息。通过反射可以构造出非常灵活而健壮的代码。

  话不多说,上代码。

 

public class Human {
    private String name;
    private int age;
    
    static{
        System.out.println("human静态代码块加载...");
    }
    
    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;
    }
    
    public void eat(String name){
        System.out.println(name+":要吃饭!");
    }
    
    @Override
    public String toString() {
        return "Human [name=" + name + ", age=" + age + "]";
    }
}
public class Teacher extends Human implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int age;
    
    public Teacher(){
        
    }
    
    public Teacher(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    static{
        System.out.println("Teacher静态代码块加载...");
    }
    
    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;
    }
    
    public void teach(String name){
        System.out.println(name+"老师在教学");
    }
    
    @Override
    public void eat(String name){
        System.out.println(name+"老师吃东西");
    }
    
    private String doSth(String param ){
        return "Teacher [name=" + this.name + ", age=" + age + "] "+param;
    }
    
    @Override
    public String toString() {
        return "Teacher [name=" + name + ", age=" + age + "]";
    }
}
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //三种获取Class对象的方法。
        Class<?> clazz1 = Class.forName("testreflect.Teacher");
        Class<Teacher> clazz2 = Teacher.class;
        Teacher teacher = new Teacher();
        Class<? extends Teacher> clazz3 = teacher.getClass();
        
        //通过反射将类的基本信息打印出来
        StringBuilder sb = new StringBuilder();
        sb.append("package "+clazz1.getPackage().getName()+";\n\n");
        sb.append(Modifier.toString(clazz1.getModifiers())+" ");
        sb.append(clazz1.getSimpleName()+" ");
        sb.append("extends "+clazz1.getSuperclass().getSimpleName()+" ");
        if(clazz1.getInterfaces().length > 0 ){
            sb.append("implements ");
            for(Class<?> c : clazz1.getInterfaces()){
                sb.append(c.getSimpleName()+",");
            }
            sb.setCharAt(sb.length()-1, ' ');
            sb.append("{\n");
        }else{
            sb.append("{\n");
        }
        for(Field field : clazz1.getDeclaredFields()){
            sb.append("    "+Modifier.toString(field.getModifiers())+" ");
            sb.append(field.getType().getSimpleName()+" ");
            sb.append(field.getName()+";\n");
        }
        for(Constructor<?> constructor : clazz1.getConstructors()){
            sb.append("    "+Modifier.toString(constructor.getModifiers())+" ");
            sb.append(clazz1.getSimpleName()+" ");
            sb.append("(");
            if(constructor.getParameters().length > 0){
                for(Parameter parameter : constructor.getParameters()){
                    sb.append(parameter.getType().getSimpleName()+" ");
                    sb.append(parameter.getName()+",");
                }
                sb.setCharAt(sb.length()-1, ')');
            }else{
                sb.append(")");
            }
            sb.append(" {}\n\n");
        }
        for(Method method : clazz1.getDeclaredMethods()){
            sb.append("    "+Modifier.toString(method.getModifiers())+" ");
            sb.append(method.getReturnType().getSimpleName()+" ");
            sb.append(method.getName()+" (");
            if(method.getParameters().length > 0){
                for(Parameter parameter : method.getParameters()){
                    sb.append(parameter.getType().getSimpleName()+" ");
                    sb.append(parameter.getName()+",");
                }
                sb.setCharAt(sb.length()-1, ')');
            }else{
                sb.append(")");
            }
            sb.append(" {}\n\n");
        }
        sb.append("}");
        System.out.println(sb);
    }
}

结果:

human静态代码块加载...
Teacher静态代码块加载...
package testreflect;


public Teacher extends Human implements Serializable {
    private static final long serialVersionUID;
    private String name;
    private int age;
    public Teacher (String arg0,int arg1) {}


    public Teacher () {}


    public String toString () {}


    public String getName () {}


    public void setName (String arg0) {}


    public int getAge () {}


    public void teach (String arg0) {}


    public void eat (String arg0) {}


    private String doSth (String arg0) {}


    public void setAge (int arg0) {}


}

 
public class Test2 {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("testreflect.Teacher");
        Constructor<?> constructor = clazz.getConstructor();
        Teacher teacher = (Teacher) constructor.newInstance();
        teacher.setName("kyle");
        teacher.setAge(20);
        Method doSth = clazz.getDeclaredMethod("doSth", String.class);
        doSth.setAccessible(true);
        Object result = doSth.invoke(teacher, "just do it");
        System.out.println(result);
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(teacher, "stan");
        System.out.println(teacher);
    }
}

结果:

human静态代码块加载...
Teacher静态代码块加载...
Teacher [name=kyle, age=20] just do it
Teacher [name=stan, age=20]

上面的代码展示了反射的一些基本功能,通过上述代码测试可知,Class.forName("testreflect.Teacher")和Teacher.class获取Class对象时是有区别的,前者在加载.class文件后会进行初始化,而后者却不会。

posted @ 2018-01-08 17:46  KyleInJava  阅读(157)  评论(0编辑  收藏  举报