【Java学习笔记】66:认识Java中的Reflection(反射)机制,获取类的属性和方法

反射部分一直欠着,现在学框架和Servlet必须要学一下了。最近学习Struts2框架和Servlet时候,很多地方直接给出类名就可以去使用了,如在web.xml中配置Filter时:

<filter>
    <filter-name>Filter1</filter-name>
    <filter-class>myFilter.Filter1</filter-class>
    <init-param>
        <param-name>who</param-name>
        <param-value>汪汪汪汪</param-value>
    </init-param>
</filter>

直接给出了包名.类名,却可以使用它。又如在Sturts2框架struts.xml中配置Action时:

<action name="main" class="myAction.MainAction">
    <result name="error">/login2.jsp</result>
</action>

直接给出了实现类的位置,在代码中并没有new 构造器()一个这个类的对象,却能使用它的对象。这些部分都使用到了反射。

简述反射

反射机制就是通过RTTI(运行时类型识别),在Java程序运行时能够对任意一个类构造对象、获取和使用成员变量和方法,对任意一个对象判断所属的类、使用成员方法。因为是任意一个,意味着反射可以越过权限检查,并且会破坏封装性。

实际上的做法是将这个类中的各类信息映射成了对象,所以才能直接使用。

Class对象及其获取

Class对象是Java类编译成class文件时生成在class文件内的,它是java.lang.Class的实例,用来保存Java类本身的类型信息。

获取Class对象可以用Objet类的getClass()成员方法,可以用数据类型的class属性直接获取,也可以用Class.forName("类名")获取:

package testReflect;

//自定的一个类
class MyClass {

}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        // 对象调用getClass()获取
        Class cls1 = new MyClass().getClass();
        System.out.println(cls1);

        // 获取class成员
        Class cls2 = MyClass.class;
        System.out.println(cls2);
        // 对基本数据类型也可以
        Class cls_dbl = double.class;
        System.out.println(cls_dbl);

        // Class.forName()加载
        try {
            Class cls3 = Class.forName("testReflect.MyClass");
            System.out.println(cls3);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

class testReflect.MyClass
class testReflect.MyClass
double
class testReflect.MyClass

反射主要是在用第三种方法,在没有导入类时根据位置加载Class对象。

获取类的成员变量

package testReflect;

import java.lang.reflect.Field;
import java.util.Date;

//自定的一个类
class MyClass {
    private int int_prvt;// 私有int
    public double dbl_pblc;// 公有double
    private Date dt_prvt;// 私有Date
    public MyClass mc_pblc;// 公有MyClass
}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        try {
            // 加载Class对象
            Class cls = Class.forName("testReflect.MyClass");
            System.out.println("加载了:" + cls.getName() + "类");
            // 获取所有的public属性
            Field[] ary_fd1 = cls.getFields();
            System.out.print("所有的public属性:");
            for (Field f : ary_fd1) {
                System.out.print(f.getName() + " ");
            }
            System.out.println();
            // 获取所有的属性
            Field[] ary_fd2 = cls.getDeclaredFields();
            System.out.print("所有的属性:");
            for (Field f : ary_fd2) {
                System.out.print(f.getName() + " ");
            }
            System.out.println();
            // 获取指定的public属性
            Field fd3 = cls.getField("mc_pblc");
            System.out.println("指定的public属性:" + fd3.getName());
            // 获取指定的属性
            Field fd4 = cls.getDeclaredField("dt_prvt");
            System.out.println("指定的属性:" + fd4.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
}

输出:

加载了:testReflect.MyClass类
所有的public属性:dbl_pblc mc_pblc 
所有的属性:int_prvt dbl_pblc dt_prvt mc_pblc 
指定的public属性:mc_pblc
指定的属性:dt_prvt

获取类的成员方法

package testReflect;

import java.lang.reflect.Method;
import java.util.Date;

//自定的一个类
class MyClass {
    private int int_prvt() {
        return 0;
    };

    public double dbl_pblc() {
        return 0.0;
    };

    private Date dt_prvt() {
        return null;
    };

    public MyClass mc_pblc() {
        return this;
    };
}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        try {
            // 加载Class对象
            Class cls = Class.forName("testReflect.MyClass");
            System.out.println("加载了:" + cls.getName() + "类");
            // 获取所有的public方法
            Method[] ary_mthd1 = cls.getMethods();
            System.out.print("所有的public方法(包括父类的):");
            for (Method m : ary_mthd1) {
                System.out.print(m.getName() + " ");
            }
            System.out.println();
            // 获取所有的方法
            Method[] ary_mthd2 = cls.getDeclaredMethods();
            System.out.print("所有的方法:");
            for (Method m : ary_mthd2) {
                System.out.print(m.getName() + " ");
            }
            System.out.println();
            // 获取指定的public方法
            Method mthd3 = cls.getMethod("mc_pblc");
            System.out.println("指定的public方法:" + mthd3.getName());
            // 获取指定的方法
            Method mthd4 = cls.getDeclaredMethod("dt_prvt");
            System.out.println("指定的方法:" + mthd4.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
}

输出:

加载了:testReflect.MyClass类
所有的public方法(包括父类的):mc_pblc dbl_pblc wait wait wait equals toString hashCode getClass notify notifyAll 
所有的方法:mc_pblc dt_prvt int_prvt dbl_pblc 
指定的public方法:mc_pblc
指定的方法:dt_prvt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值