Java反射学习日记一(反射的基本概念与Class、Constructor、Method、Field的基本应用)

反射的基本概念与Class、Constructor、Method、Field的基本应用

·反射的基本概念

    在正常情况下,如果要使用一个类,则必须按照如下步骤操作:

        ·使用import导入类所在的包(类:java.lang.Class)

        ·明确使用类名称或者接口名称定义对象

        ·通过关键字new进行类对象实例化(构造方法:java.lang.reflect.Constructor)

        ·产生对象可以使用"对象.属性"进行类中属性的调用(属性:java.lang.reflect.Field)

        ·通过"对象.方法()"调用类的中方法(方法:java.lang.reflect.Method)

    而反射的过程,不需要有明确类型的对象,所有的对象使用Object表示:

        ·可以直接利用Object与反射机制的混合 调用类中的方法。

·Class、Constructor、Method、Field的基本应用

1、Class类

    Class类是整个反射操作的源头,而这个类的定义如下:


    但是要使用Class类进行操作,就必须首先参数Class类的实例对象,而有如下三种方式可以产生Class类的实例对象:

        ·方式一:Object类提供了一个返回Class类对象的方法:public Class<?>getClass();

        ·方式二:利用"类.class"取得

        ·方式三:利用class类的static方法取得:

                public static Class<?>forName(String className)Throws ClassNotFoundException

    如果是程序设计的人员,使用最多的是forName()方法,如果是使用者,肯定会使用"类.class",而工厂设计模式最好利用反射机制进行解耦合。

2、利用反射实例化对象

    Class类如果使用了forName()方法之后,就可以使用Class类定义的newInstance()方法默认去调用类之中的无参构造方法
		Class<?> cls =  Class.forName("CollectionStudy.Student");
		//相当于关键之new实例对象,等价于:Object obj = new Student();
		Object obj = cls.newInstance();

    全局代码:

执行输出


        到此非常清楚的发现,在整个编写过程即使完全不知道类结构,即使不导入包.类,也可以 进行类的对象实例化操作。

3、操作构造方法

    但是如果使用反射实例化类对象,必须要求类中存在无参构造方法,因为默认使用Class类的newInstance()方法只能够找到无参构造方法。这个时候只能够取得类中的构造方法,传递所需要的参数后才可以执行。

    在Class类中定义了可以取得一个类中构造方法的操作:

        ·取得类中的全部构造:public Constructor<?> [] getConstructors()

        ·取得类中的指定参数构造:public Constructor <T> getConstructor(Class<?>... parameterTypes)

范例:获得类中全部构造方法


输出结果:

        所以如果现在要想进行指定构造方法的调用,就必须明白Constructor类。在此类中定义了一个实例化对象方法:

        public T newInstance(Object... initargs) 

范例:实例化student有参构造


Student类


    正是因为如果通过构造方法实例化对象规格不统一,所以在进行简单JAVA类操作的时候,就必须给出无参构造方法。

4、调用类中的方法

    取得一个类中的实例对象之后,下面主要的任务就是要调用类之中可以使用的操作方法,对于一个类中的方法,实际上有两类方法:

        ·取得父类继承而来的方法

            -取得全部方法:public Method[] getMethods() 

            -取得指定方法:public Method getMethod(String name,Class<?>... parameterTypes)

        ·取得本类定义的方法

            -取得全部方法:public Method[] getDeclaredMethods() 

            -取得指定方法:public Mehtod getDeclaredMethod(String name,Class<?>...parameterTypes)

    但是以上操作在方法定义上区别不大,因为方法大部分是public,所以两种方式取得的结果是没有区别的。

范例:取得全部方法


        再Method类中有一个至关重要的方法:

                ·调用:public Object invoke(Object obj,Object... args)

范例:反射调用类中的方法

		Class<?> cls =  Class.forName("CollectionStudy.Student");
		Object obj = cls.newInstance();
		Method setMethod = cls.getDeclaredMethod("setName", String.class);
		Method getMethod = cls.getDeclaredMethod("getName");
		setMethod.invoke(obj, "沉思");
			System.out.println(getMethod.invoke(obj));

5、调用类中的属性(尽量不用)

    关于类之中的属性,也可以用反射进行操作,而支持的方法也有两类:

        ·取得所有继承而来的属性:

            -取得全部属性:public Field[] getFields() 

            -取得指定属性:public Field getField(String name) 

        ·取得本类属性:

            -取得全部属性:public Field[] getDeclaredFields() 

            -取得指定属性:public Field getDeclaredField(String name) 

范例:取得一个类中的全部属性


        在Field类中还定义有进行属性调用的方法:

            ·设置属性内容:public void set(Object obj,Object value)

            ·取得属性内容:public Object get(Object obj)

在Constructor、Method、Field三个类上有一个共同的父类AccessiableObject,

在这个类中定义了可以取消封装的操作:

使用Field.setAccessible(true)

范例:直接操作属性



    在开发中,只需要灵活使用Class、Constructor、Method、Field就可以使用反射进行一系列操作的代码实现。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值