本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(3)

java反射

发布于2021-03-13 14:41     阅读(1350)     评论(0)     点赞(0)     收藏(0)


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("悄悄说话");
    }
}

原文链接:https://blog.csdn.net/qq_37665301/article/details/114678599



所属网站分类: 技术文章 > 博客

作者:哦哦好吧

链接:http://www.javaheidong.com/blog/article/114716/491a9c7d8c2fe1c9d0eb/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

0 0
收藏该文
已收藏

评论内容:(最多支持255个字符)