反射机制及其应用

一个类 有组多个组成部分,例如成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。反射常常用于框架。

加载类
这里写图片描述

反射机制及其应用_第1张图片

如图的操作便可以进行类的加载,通过如下的常用方法可以解剖类:

反射机制及其应用_第2张图片

这些方法可以解剖出构造函数,方法和成员变量(属性)。前三种解剖调出的是声明为public的内容,如声明为private的组成部分,需要使用后三种方法。

解剖出这些成员的作用:

构造函数:创建对象,完成数据初始化,可以利用解剖出的构造函数进行创建对象;字段:封装数据,解剖出可以用于封装数据;成员方法:解剖出之后可以使用。

通过反射的构造函数创建对象:

package cn.itcast.reflrct;

import java.util.List;

public class Person {
    String name = "aaa";
    public Person(){
        System.out.println("person");
    }
    public Person(String name){
        System.out.println("person name password");
    }
    private Person(List list){
        System.out.println(list);
    }
    public void aa1(){
        System.out.println("aa1");
    }
    public void aa1(String name,int password){
        System.out.println(name + ":" + password);
    }
}
package cn.itcast.reflrct;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
//反射类的构造函数,创建类对象
public class demo2 {
    //反射构造函数
    @Test
    public void test1() throws Exception {
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Constructor c = clazz.getConstructor(null);
        Person p =(Person)c.newInstance(null);//newInstance返回的是Object,需要进行类型转换
        System.out.println(p.name);
    }
    @Test
    public void test2() throws Exception{
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Constructor c= clazz.getConstructor(String.class);//表示是String类型参数的构造函数
        Person p = (Person)c.newInstance("xxxx");
        System.out.println(p.name);
    }
    @Test
    public void test3() throws Exception{
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Constructor c= clazz.getConstructor(List.class);//表示是可变参数类型参数的构造函数
        c.setAccessible(true);//暴力反射,正常私有成员不许外界反射
        Person p = (Person)c.newInstance(new ArrayList());
        System.out.println(p.name);
    }
    //创建对象的另一种方法
    @Test
    public void test4() throws Exception{
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Person p = (Person) clazz.newInstance();//要求Person类必须要有无参的构造函数
        //无参的情况下等效于test1()
        System.out.println(p.name);
    }
    //反射类方法
    @Test
    public void test5() throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Method method = clazz.getMethod("aa1",String.class,int.class);//对于private方法使用getDeclaredMethod()
        method.invoke(p, "asd",38);//如果为static方法,可以不需要对象
    }
    //反射main方法
    @Test
    public void test5() throws Exception{
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Method method = clazz.getMethod("main",String[].class);
        method.invoke(null,new Object[](new String[]("aaa","bbb"));//此处为通过反射调用参数为数组的方法,需要注意,为static方法,可以不需要对象,所以为null
    }
        //反射字段
    @Test
    public void test6() throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("cn.itcast.reflrct.Person");
        Field f = clazz.getField("name");//获取字段name,getField内填写字段名称
        Class type = f.getType();//获取字段类型
        if(type.equals(String.class)){
            String name = (String) f.get(p);
            System.out.println(name);
        }
        //设置字段值
        f.set(p, "sssss");
        System.out.println(p.name);
    }
}

使用Junit进行单元测试,此处用反射类方法举例:

反射机制及其应用_第3张图片

你可能感兴趣的:(Java)