java反射机制

在java语言中,如果不知道某个对象的确切信息,RTTI(运行时类型识别)可以告诉我们,但是前提是此类型在编译时已知。java不是一门动态语言,但他却具备动态加载的能力。这种制度提供了java语言与未知类型打交道的能力,使得java程序员在编码时代码的可扩展性更强,java语言因而变得更加丰富。

  • java反射:在程序运行期间加载,探寻,使用编译期间完全未知的类。RTTI和反射最大的区别是对于RTTI来说会在编译时打开和检查.class文件,而反射只能在运行时打开和检查.class文件。
    java反射的使用:
public class ReflectPerson {
    private int age  = 1;
    // sex = true为男,sex = false为女
    private boolean sex = true;

    public ReflectPerson(){

    }

    protected ReflectPerson(int age){
          this.age = age;
    }

    public  ReflectPerson(int age,boolean sex){
        this.age = age;
        this.sex = sex;
    }

    public void printAge(int age){
        System.out.println("年龄为 : "+age);
    }

    protected void printSex(boolean sex){
        if (sex){
            System.out.println("性别为 : "+ "男");
            return;
        }
        System.out.println("性别为 : "+ "女");
    }

    public ReflectPerson(){

    }

    private void testPrivateMethod(String str){
        System.out.println("反射调用private修饰的方法"+str);
    }

    public int getAge() {
        return age;
    }

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

    public boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }
}

复制代码
public class MeetReflect {

    // 用法、使用 - - usage
    private static String usage = "usage";

    public static void main(String[] args){

        try {
            App app = new App();
            // ================= 构造器 (Constructor)=======================================
            Class<?> c =  Class.forName("com.cx.reflect.ReflectPerson");
            Object obj = c.newInstance();
            System.out.println("getDeclaredConstructors()获取的所有构造器,包含private、protected修饰的构造器");
            Constructor<?>[] constructors = c.getDeclaredConstructors();
            for (Constructor<?> constructor : constructors) {
                System.out.println(constructor);
            }
            Constructor<?>[] constructors1 = c.getConstructors();
            System.out.println("getConstructors()获取的所有构造器,只能获取public修饰的构造器");
            for (Constructor<?> constructor1 : constructors1) {
                System.out.println(constructor1);
            }
            // 获取类中public修饰的无参构造器,必须使用public修饰,不能是Default的
            Constructor<?> constructor1 = c.getConstructor();
            // 获取类中特定参数的构造器
            Constructor<?> constructor2 = c.getConstructor(int.class,boolean.class);
            // 通过指定的构造器创建对象
            constructor2.newInstance(1,true);


            // ================= 方法 (Method) =======================================
            System.out.println("获取所有public修饰的方法,包括从父类继承过来的方法");
            Method[] methods = c.getMethods();
            for (Method method : methods){
                System.out.print(method.getName() + " ");
            }
            System.out.println("");
            System.out.println("获取类所有的方法,包括private修饰的方法");
            Method[] methods2 = c.getDeclaredMethods();
            for (Method method : methods2){
                System.out.print(method.getName() + " ");
            }
            // 获取某个特定的方法
            Method method = c.getMethod("printAge",int.class);
            // 调用改方法
            method.invoke(obj,5);

            // 调用private修饰的方法
            Method privateMethod = c.getDeclaredMethod("testPrivateMethod",String.class);
            // 必须将方法设置成可访问的,否则会报错
            privateMethod.setAccessible(true);
            privateMethod.invoke(obj,"i am testing!!");

            // ================= 属性 (Filed) =======================================
            System.out.println("获取所有public修饰的属性,包括从父类继承过来的方法");
            Field[] fields = c.getDeclaredFields();
            Object obj1 = constructor2.newInstance(5,false);
            for (Field field : fields){
                field.setAccessible(true);
                // 通过反射修改对象的属性
                if (field.getType() == int.class){
                    field.setInt(obj1,1);
                }else if (field.getType() == boolean.class){
                    field.setBoolean(obj1,true);
                }
                Object value = field.get(obj1);
                System.out.println(field.getName() + " : " +value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
/*
运行结果:
getDeclaredConstructors()获取的所有构造器,包含private、protected修饰的构造器
public com.cx.reflect.ReflectPerson(int,boolean)
protected com.cx.reflect.ReflectPerson(int)
public com.cx.reflect.ReflectPerson()
getConstructors()获取的所有构造器,只能获取public修饰的构造器
public com.cx.reflect.ReflectPerson(int,boolean)
public com.cx.reflect.ReflectPerson()
获取所有public修饰的方法,包括从父类继承过来的方法
printAge getAge setAge isSex setSex wait wait wait equals toString hashCode getClass notify notifyAll 
获取类所有的方法,包括private修饰的方法
printAge testPrivateMethod printSex getAge setAge isSex setSex 年龄为 : 5
反射调用private修饰的方法i am testing!!
获取所有public修饰的属性,包括从父类继承过来的方法
age : 1
sex : true
*/
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值