Java基础之反射

2018-11-29  本文已影响0人  沐左

Java基础之—反射(非常重要)
Java中反射机制详解
Java进阶之reflection(反射机制)——反射概念与基础
浅谈java反射机制

package zuo.com.javademo.bean;

/**
 * Person实体类
 * @author zuo
 * @date 2018/9/18 21:55
 */
public class Person {
    private int id;
    private String name;
    private int age;

    public Person() {
    }

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    private Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    private int getAge() {
        return age;
    }

    private void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

反射的定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


API

java 8 API

反射涉及的类,除了Class类之外,基本上都在java.lang.reflect包里面,常用的类有Constructor,Field,Method类等,AccessibleObject类是前面三个类的基类,主要包含设置安全性检查等方法。

reflect

在类加载的时候,jvm(Java 虚拟机)会创建一个class对象(字节码对象)

class对象(字节码对象)是可以说是反射中最常用的,获取class对象(字节码对象)的方式的主要有三种

Class clazz  = Person.class;    
Class clazz = p.getClass();    
//Class clazz = Class.forName("全限定类名");
Class clazz = Class.forName("zuo.com.javademo.bean.Person");

类的构造函数

当我们拿到一个类的构造函数之后,我们就可以轻易的创建类的对象了。常用的方法有:

Class aClass = Class.forName("zuo.com.javademo.bean.Person");
Constructor[] constructors = aClass.getConstructors();
Class aClass = Class.forName("zuo.com.javademo.bean.Person");
Constructor constructor = aClass.getConstructor(int.class,String.class);
    @Test
    public void constructorTest() throws Exception {
        Class aClass = Class.forName("zuo.com.javademo.bean.Person");
        Constructor[] constructors = aClass.getConstructors();
        for (int i = 0; i < constructors.length; i++) {
            Class<?> parameterTypesClass[] = constructors[i].getParameterTypes();
            System.out.print("第" + i + "个构造函数:\t (");
            for (int j = 0; j < parameterTypesClass.length; j++) {
                System.out.print(parameterTypesClass[j].getName() + (j == parameterTypesClass.length - 1 ? "" : "\t"));
            }
            System.out.print(")\n");
        }

        Class bClass = Class.forName("zuo.com.javademo.bean.Person");
        Constructor constructor = bClass.getConstructor(int.class, String.class);
        Class<?> parameterTypesClass[] = constructor.getParameterTypes();
        System.out.print("指定构造函数:\t (");
        for (int j = 0; j < parameterTypesClass.length; j++) {
            System.out.print(parameterTypesClass[j].getName() + (j == parameterTypesClass.length - 1 ? "" : "\t"));
        }
        System.out.print(")\n");
    }
测试结果

类的方法

获取类方法的相关方法


获取类的方法
Class aClass = Class.forName("zuo.com.javademo.bean.Person");
Method setId = aClass.getMethod("setId", int.class);
 Method[] methods = aClass.getMethods();
Method[] methods1 = aClass.getDeclaredMethods();
 //注意:只有取消安全性检查设置后才可以调用private修饰的方法,取消所有方法的安全性检测
Method.setAccessible(methods1, true);

获取私有无参方法

 Method getAge = aClass.getDeclaredMethod("getAge");
//注意:只有取消安全性检查设置后才可以调用private修饰的方法,取消该方法的安全性检测
getAge.setAccessible(true);

获取私有有参方法

Method setAge = aClass.getDeclaredMethod("setAge",int.class);
//注意:只有取消安全性检查设置后才可以调用private修饰的方法,取消该方法的安全性检测
setAge.setAccessible(true);
//调用方法,需要先获取类的对象
Object person = aClass.newInstance();
//调用setAge方法,使用Method 的 invoke方法,需要传入类的对象和方法的参数
Object back = setAge.invoke(person, 25);
 //因为setAge方法的返回类型为 void 所以 back = null
int age = (int) getAge.invoke(person);
//getAge方法的返回类型为 int ,我们用 int 来接收一下 , 因为之前调用来 setAge ,所以我们获取到的 age=25

此时person 对象 :Person{id=0, name='null', age=25}

Constructor constructor = aClass.getConstructor(int.class, String.class);
Object instance = constructor.newInstance(2, "迈克尔");

通过构造函数获取的对象:Person{id=2, name='迈克尔', age=0}

测试结果

类的属性

1、getFields():获取所有的"公有字段"

2、getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;

3、getField(String fieldName):获取某个"公有的"字段;

4、getDeclaredField(String fieldName):获取某个字段(可以是私有的);

5、public void set(Object obj,Object value);设置字段的值
参数说明:
 *obj:要设置的字段所在的对象;
 *value:要为字段设置的值;

6、获取对应字段的值
get(Object obj);  //obj:要设置的字段所在的对象;
------
 Class<?> buildconfig = Class.forName("com.kingoit.yzt.BuildConfig");
String flavor = String.valueOf(buildconfig.getField("FLAVOR").get(buildconfig));
上一篇下一篇

猜你喜欢

热点阅读