java反射

反射

反射:将类的各个组成部分封装为其他对象。

代码

import dxt.test.domain.Person;

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

/**
 * 学习反射一
 * 反射:将类的各个部分封装为其它对象
 * 获取Class对象的三种方式:
 *  1. 源代码阶段:Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
 *  2. Class类对象阶段:类名.class:通过类名的属性class获取
 *  3. Runtime运行时阶段:对象.getClass():getClass()方法在Object类中定义。
 *  4. 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象
 *  都是同一个。
 * 学习反射二
 *  1. 获取成员变量
 *   <一>: 获取成员变量
 *      Field[] getFields() : 获取public修饰的属性
 *      Field[] getDeclaredFields() : 获取全部属性
 *      Field getField(String name) : 获取public修饰的对应name的属性
 *      Field getDeclaredField(String name) : 获取任意修饰的对应name的属性
 *   <二>: 操作成员变量(get/set---获取/设置)
 *      (1)首先要有一个对应类Person的对象p
 *      (2)然后通过反射方式获取对象p中的对应属性值
 *          已经通过反射获取了对应类中的对应属性---field
 *          然后这个对应类声明了一个对象p,可以通过get方法获取对象p中属性field的对应值
 *          Object get(Person p), 需要field来调用
 *          void set(Object obj, Object value)
 *      (3)注意:private修饰的属性值不可以直接访问
 *              需要设置忽略权限修饰符的安全检查
 *              field.setAccessible(true);
 *  2. 获取构造函数
 *   <一> Constructor[] getConstructors() : 获取所有的构造方法
 *        Constructor getConstructor(Class... parameterTypes) : 获取对应参数列表的构造方法
 *   <二> 使用构造方法创建对象
 *          constructor.newInstance(Object... initarges)
 *   <三> 直接使用反射获取的Class对象来创建对象
 *  3. 获取成员方法
 *   <一>四个函数
 *      Method[] getMethods() : 会获取父类的方法
 *      Method getMethod(String name, Class... parameterType)
 *      Method[] getDeclaredMethods()
 *      Method getDeclaredMethod()
 *   <二>执行成员方法
 *      (1)注意是否需要暴力反射
 *      (2)invoke()方法
 *
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {
        //1. 获取Class对象
        //1.1 Class.forName("全类名")
        Class clazz1 = Class.forName("dxt.test.domain.Person");
        System.out.println(clazz1);

        //1.2 类名.class
        Class clazz2 = Person.class;
        System.out.println(clazz2);
        //1.3 对象.getClass();
        Person p = new Person();
        Class clazz3 = p.getClass();
        System.out.println(clazz3);
        //1.4 在不同阶段获得的Class对象是否为同一个
        System.out.println(clazz1 == clazz2);   //true
        System.out.println(clazz2 == clazz3);

        //2. 获取成员变量:
        //2.1 获取public成员变量
        //2.1.1 Field[] getFields() : 获取所有public修饰的成员变量
        Field[] fields_getFields = clazz1.getFields();
        for(Field f : fields_getFields){
            System.out.println(f.toString());
        }
        //2.1.2 Field getField(String name) : 获取指定名称的public修饰的成员变量
        Field field_getField = clazz1.getField("height");
        System.out.println(field_getField.toString());
        //2.2 操作成员变量
        //2.2.1 获取成员变量 field_getField的值
        Person p2 = new Person();
        Object obj = field_getField.get(p2);
        System.out.println(obj);
        //2.2.2 设置成员变量 field_getField的值(不需要在Person类中设置set方法依然可以设置)
        field_getField.set(p2, 100);
        System.out.println(p2);
        //2.3 获取所有的成员变量
        Field[] fields_getDeclaredFields = clazz1.getDeclaredFields();
        for(Field f : fields_getDeclaredFields){
            System.out.println(f.toString());
        }
        Field field_getDeclaredField = clazz1.getDeclaredField("name");
        System.out.println(field_getDeclaredField);
        //2.4 操作private修饰的成员变量(访问前需要设置忽略权限修饰符的安全检查)
        field_getDeclaredField.setAccessible(true); //设置忽略权限修饰符的安全检查,又称暴力反射
        Object obj2 = field_getDeclaredField.get(p2);
        System.out.println(obj2);

        //3. 获取构造函数
        //3.1 Constructor[] getConstructors() : 获取所有的构造方法
        Constructor[] constructors = clazz2.getConstructors();
        for(Constructor c : constructors){
            System.out.println(c.toString());
        }
        //3.2 Constructor getConstructor() : 依据参数列表获取对应的构造方法
        Constructor constructor = clazz2.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //3.3 使用构造方法创建对象: T newInstance(Object... initarges)
        Person p3 = (Person)constructor.newInstance("dxt", 18);
        System.out.println(p3);
        //3.4 可以直接使用放射获取的Class对象来创建对象
        Person p4 = (Person)clazz2.newInstance();   //不推荐使用

        //4. 获取成员方法
        //4.1 获取所有public修饰的方法 , 不会有private修饰的方法,但会有其父类的public方法
        //  Method[] getMethods()
        Method[] methods = clazz3.getMethods();
        for(Method m : methods){
            System.out.println(m.toString());
        }
        //4.2 获取public修饰的对应方法 : Method getMethod(String name, Class... parameterType)
        Method method = clazz3.getMethod("setAge", int.class);
        System.out.println(method.toString());
        //4.3 获取所有的方法
        //  Method[] getDeclaredMethods(): 只会得到本类中声明的所有方法
        //  Method getDeclaredMethod(String name, Class...parameterType)
        Method[] methods2 = clazz3.getDeclaredMethods();
        for(Method m : methods2){
            System.out.println(m.toString());
        }
        //4.4 执行方法
        Method method2 = clazz3.getDeclaredMethod("talk");
        method2.setAccessible(true);    //同样需要设置忽略权限修饰符的安全检查
        Person p5 = new Person();   //需要一个对象作为参数
        method2.invoke(p5);
    }
}

使用到的Person类

public class Person {
    private String name;
    private int age;
    public int height;

    public Person(){}

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

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;
    }

    @Override
    public String toString(){
        return name + "\t" + age + "\t" + height;
    }

    private void talk(){
        System.out.println("悄悄说话");
    }
}

实现过程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值