java反射

Java反射

  • 反射是java语言一个非常重要的特点,通过反射,可以在运行时获取类的信息,创建对象,操作对象的属性,执行对象的方法,获取注解等。

  • 在日常的开发过程中,反射的使用可能并不多,所以比较的陌生,但了解熟悉后,反射还是比较简单的,只是对一些API的运用。

  • 反射主要涉及Class类和java.lang.reflect包中类。

下面通过实际的代码来说明反射的使用:

ReflectionDemo.java

package com.example;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by hehelt on 16/7/30.
 */
public class ReflectionDemo {

    public static void main(String[] args) {

        /*------------------获取Class,总共有三种方法--------------------------*/
//        Class personClass = getPersonClass(1);
//        Class personClass = getPersonClass(2);
//        Class personClass = getPersonClass(3);

        /*----------------创建对象-----------------*/
//        createPerson();


        /*------------------操作属性--------------------------*/
//        getFields();
//        getField("age");
//        getFieldValue();
//        setFieldValue();

        /*----------------操作方法----------------*/

//        getMethods();
//        doMethod();

//        getAnnotation();

    }


    /**
     * 获取Class对象,总共三种方法
     *
     * @param index 方法的序号
     * @return
     */
    private static Class getPersonClass(int index) {

        Class personClass = null;

        switch (index) {
            case 1:
                // 第一种方法,直接类名后加上.class
                personClass = Person.class;

                break;

            case 2:
                // 第二种方法,每一个对象都有getClass()方法
                Person person = new Person();
                personClass = person.getClass();
                break;

            case 3:
                // 第三种方法,Class的静态方法forName(String className),className为包名+类名
                try {
                    personClass = Class.forName("com.example.Person");
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                break;

        }

        return personClass;
    }


    /**
     * 创建对象
     */
    public static void createPerson() {
        Class personClass = getPersonClass(1);

        try {

            // 无惨构造函数
            Constructor constructor = personClass.getConstructor(null);
            Person person = (Person) constructor.newInstance(null);
            System.out.println(person.getName());

            // 有参构造函数
            Constructor constructor1 = personClass.getConstructor(String.class);
            person = (Person) constructor1.newInstance("haha");
            System.out.println(person.getName());

            // 构造函数为private时
            Constructor constructor2 = personClass.getDeclaredConstructor(int.class, String.class);
            constructor2.setAccessible(true);
            person = (Person) constructor2.newInstance(13, "hello");
            System.out.print(person.getName());

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取所有的属性
     */
    public static void getFields() {

        Class personClass = getPersonClass(3);

        // 权限为public的属性
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

        // 所有属性
        fields = personClass.getDeclaredFields();
        personClass.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }
    }

    /**
     * 根据属性名称获取属性
     */
    public static void getField() {

        Class personClass = getPersonClass(3);

        try {

            // 属性的权限为public
            Field field = personClass.getField("name");
            System.out.println(field.getName());

            // 属性的权限不为public
            Field ageField = personClass.getDeclaredField("age");
            System.out.println(ageField.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取对象的属性值
     */
    private static void getFieldValue() {
        Class personClass = getPersonClass(3);

        Person person = new Person();

        try {

            // 权限不为public的属性
            Field field = personClass.getDeclaredField("age");
            field.setAccessible(true);// 默认为false,为true时,系统不会验证权限;为false时,系统会检验权限.当需要操作的属性不为public时,需要设置该值为true,避免权限不足导致操作失败.
            int age = field.getInt(person);
            System.out.println(age);

            // 权限为public的属性
            Field nameField = personClass.getField("name");
            String name = (String) nameField.get(person);
            System.out.println(name);

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 设置属性的值
     */
    public static void setFieldValue() {
        Class personClass = getPersonClass(3);
        Person person = new Person();
        try {

            // 属性的权限为public
            Field field = personClass.getField("name");
            System.out.println(field.get(person));
            field.set(person, "hehe");
            System.out.println(field.get(person));

            // 属性的权限不为public
            Field ageField = personClass.getDeclaredField("age");
            ageField.setAccessible(true);// 默认为false,为true时,系统不会验证权限;为false时,系统会检验权限.当需要操作的属性不为public时,需要设置该值为true,避免权限不足导致操作失败.
            System.out.println(ageField.getInt(person) + "");
            ageField.set(person, 10);
            System.out.println(ageField.getInt(person) + "");

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取类的方法
     */
    public static void getMethods() {

        Class personClass = getPersonClass(3);

        // 权限为public的方法,包括父类中的方法
        Method[] methods = personClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        System.out.println("--------------");
        // 所有属性,不包括父类的方法
        methods = personClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
    }


    /**
     * 获取类的方法
     */
    public static void getMethod() {

        Class personClass = getPersonClass(3);

        try {

            Method getNameMethod = personClass.getMethod("getName");
            System.out.println(getNameMethod.getName());

            Method setNameMethod = personClass.getMethod("setName", String.class);
            System.out.println(setNameMethod.getName());

            Method getAgeMethod = personClass.getDeclaredMethod("getAge");
            System.out.println(getAgeMethod.getName());

            Method setAgeMethod = personClass.getDeclaredMethod("setAge", int.class);
            System.out.println(setAgeMethod.getName());


        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行类的方法
     */
    public static void doMethod() {

        Class personClass = getPersonClass(3);
        Person person = new Person();

        try {

            // public 无参数方法调用
            Method getNameMethod = personClass.getMethod("getName");
            String name = (String) getNameMethod.invoke(person);
            System.out.println(name);

            // public 有参数方法调用
            Method setNameMethod = personClass.getMethod("setName", String.class);
            setNameMethod.invoke(person, "hehe");
            System.out.println((String) getNameMethod.invoke(person));


            // 非public 无参数方法调用
            Method getAgeMethod = personClass.getDeclaredMethod("getAge");
            getAgeMethod.setAccessible(true);
            int age = (int) getAgeMethod.invoke(person);
            System.out.println(age);

            // 非public 有参数方法调用
            Method setAgeMethod = personClass.getDeclaredMethod("setAge", int.class);
            setAgeMethod.setAccessible(true);
            setAgeMethod.invoke(person, 12);
            System.out.println((int) getAgeMethod.invoke(person));


        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


    }


    /**
     * 获取注解
     */
    public static void getAnnotation() {
        Class personClass = getPersonClass(3);
        try {

            Field field = personClass.getField("name");
            MyAnnotation annotation = (MyAnnotation) field.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.MyNameValue());

            Field ageField = personClass.getDeclaredField("age");
            MyAnnotation ageAnnotation = (MyAnnotation) ageField.getAnnotation(MyAnnotation.class);
            System.out.println(ageAnnotation.MyNameValue());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }

}

MyAnnotation.java

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by hehelt on 16/8/4.
 * <p>
 * 自定义的注解
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {

    String MyNameValue() default "";

}

Person.java

package com.example;


/**
 * Created by hehelt on 16/8/4.
 */

public class Person {

    @MyAnnotation(MyNameValue = "heheLT")
    public String name = "LT";

    @MyAnnotation(MyNameValue = "heheLT")
    private int age = 0;


    public String getName() {
        return name;
    }

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


    private int getAge() {
        return age;
    }

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


代码链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值