黑马程序员--Java基础加强--07.【反射创建对象 操作字段 调用方法的异同】【个人总结】

反射总结

反射创建对象       操作字段          调用方法 的异同

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

这篇日志着重阐述反射创建对象,操作字段和调用方法的步骤和形式的特点

1.    反射 Constructor, Field, Method 步骤

无论是通过Java反射 创建对象操作字段还是调用方法,获取与相关类关联Class对象的必不可少的一步

(1). 获取Class对象

[1].获取Class对象的步骤 (1次关联)

通过以字符串形式给出的全类名 ===>获取相关类Class对象

[2]. 常用的方法就是Class的静态方法forName ( )方法

【特点】在反射中以字符串形式出现全类名关联到Class对象上以后,相关类类名就不会出现在后续的反射代码中。

【举例】

Class clazz = Class.forName("cn.itcast.bean.Person");

//此后的代码中,Person就不会显示地出现在代码中。

(2). 通过Class对象创建相关类对象的步骤

[1]. 执行基础

建立获取到Class对象的基础之上

[2]. 通过反射创建对象的步骤 (2次关联)

step1:调用Class对象getConstructor(Class<?>... parameterTypes)方法

关联调用的构造函数形式参数列表[1次关联] ====>获取指定形参的构造函数Constructor的对象

【注意】这里不用关联构造方法的名字,因为构造方法的名字类名相同全类名已经在获取Class对象的时候关联进去了。

【注意】关联构造函数的形式参数原因就是构造函数存在重载,仅仅通过构造函数名称无法得知哪一个构造函数被调用。

【举例】

Constructor constructor =

clazz.getConstructor(String.class,int.class);

//注意到getConstructor(Class<?>... parameterTypes)仅仅需要形参列表的数据,//而不需要构造方法的名字

//相当于调用publicPerson(String name, int age){…}这个构造方法

step2:调用Constructor对象newInstance(Object…initArgs)方法

        关联要调用的构造方法形式参数相对应实际参数[2次关联]

【举例】

Object obj =constructor.newInstance("Benjamin", 28);

//"Benjamin" 对应 String.class

//28 对应 int.class

 

[2]. 【特点】2次关联关联构造函数形式参数(1次) 和实际参数 (1次)。不用关联构造方法名称

(3). 通过Class对象操作相关类对象的字段步骤

[1]. 执行基础

建立获取到Class对象 +通过反射创建出来的相关类对象的基础之上

[2]. 通过反射操作相关字段的步骤 (2次关联)

step1:调用Class对象getField(String name)方法

关联操作的字符串形式给出的成员字段的名字[1次关联]====>获取指定字段对应的Field的对象

【特点】在反射中以字符串形式出现字段名关联到Field类对象上以后,相关字段名就不会出现在后续的反射代码中。

【举例】

Field field =clazz.getField("country");

//field对象就和country字段相关联,操作field这个对象就相当于对country这个字段进行//操作     此后的代码中,country就不会显示地出在代码中

step2:调用Field对象set(Object obj, Object value)方法get(Object obj)

方法 【对字段的操作只有获取设置两个动作

        关联字段名对应的字段值 +对应字段所属的对象set关联对应字段所属的对象get[2次关联]

【注意】因为操作字段的方法都是setter或者getter。这个时候,Field本身也具备set( )方法或者get( )方法,所以Field知道调用哪个方法来操作字段。所以不用关联操作字段的方法名。

【举例】

field.set(obj, "China");

//设置field中关联的country字段,值为China---set

Object o =field.get(obj);  

//获取field中关联的country字段的值 –--------get

(4). 通过Class对象调用相关类对象的方法步骤

[1]. 执行基础

建立获取到Class对象 +通过反射创建出来的相关类对象的基础之上

[2]. 通过反射调用相关方法的步骤 (2次关联)

step1:调用Class对象getMethod(String name, Class<?>… parameterTypes)方法

关联操作的字符串形式给出的成员方法的名字成员方法的形式参数列表[1次关联]====>获取指定方法对应的Method的对象

【特点】在反射中以字符串形式出现方法名关联到Method类对象上以后,相关字段名就不会出现在后续的反射代码中。

【举例】

Method method =

clazz.getMethod("paramMethod", String.class,int.class);

//相当于调用public voidparamMethod(String name, int age){…}这个成员方法

step2:调用Method对象invoke(Object obj, Object…parameterTypes)方法

        关联要调用的构造方法形式参数相对应实际参数+对应字段所属的对象 [2次关联]

【举例】

method.invoke(obj, "Benjamin", 110);  

//"Benjamin" 对应 String.class

//110 对应 int.class

2). 执行步骤的相似性

(1). Class, Constructor, Field和Method执行步骤的图例


(2). 执行步骤的相似性

[1]. 一旦以字符串进行关联之后,相应的字符串中元素代码中不会再次体现会被封装对应的对象中。【Constructor类对象没有这一步】

【举例】

{1}. Class:Class clazz =Class.forName("cn.itcast.bean.Person");

之后Person不会显式写到代码中,被Class对象封装

{2}. Field:Field field=clazz.getField("country");

之后setCountry或者getCountry这样对country字段操作的方法不会有country体现。取而代之的是Field的set和get方法来做操作。

{3}. Method:Method method=clazz.getDeclaredMethod("showII",null);

之后不会出现xxx.showII( ) 这样的代码,直接被Method对象所封装。

[2]. 反射基本操作就是把传统的操作拆分开来格式化传统的操作有利于搭建框架技术

e.g.

{1}. 以传统的创建对象为例本来是 Person p =new Person(“Benjamin”,28); 但是这样的代码没有扩展性,换做Student类,又要重写为 Student s =new Student(“Benjamin”, 28);这种代码无法统一

现在使用反射来构建:

Class clazz =Class.forName(“cn.itcast.bean.Person”);

Constructor con=clazz.getConstructor(String.class, int.class);

Object obj =con.newInstance(“Benjamin”,28);

虽然原来一步的代码变成了三步,但是现在只要是为forName方法传入不同字符串,就能创建不同的对象。以上代码如果传入“cn.itcast.bean.Student”, 就能创建Student实例对象。

【结论】

{1}. 传统代码虽然使用起来简洁,但是把更多的和特定类名特定字段名或者特定方法名相关的元素以非参数的形式写死到代码中,没有办法扩充

{2}. 反射代码虽然使用起来相对麻烦,但是他将很多和特定元素相关的非参数代码统一成String类型并进行参数化,使得通用性大幅度提高,为框架技术奠定了坚实的基础。

[2]. 关联元素

{1}. 最标准关联格式【双关联就是:

(1). 关联1:调用的方法名+形参

(2). 关联2:调用的实参+操作所属的对象

【简化】由于构造方法字段有特殊的地方,所以以上的双关联格式有所简化

{2}. Constructor的简化

{2}1. 由于构造方法类名一致,类名被封装到Class对象中。所以Constructor在第一关联的部分就省去对“方法名”的关联

{2}2. 由于构造函数是用来创建对象的,不需要被某个对象调用,所以第二关联省去对“操作所属的对象”的关联

 

【举例】

//关联形参,但没有方法名

Constructor constructor =clazz.getConstructor(String.class,int.class);

 

//关联实参,但没有对应对象

Object obj =constructor.newInstance("Benjamin", 28);

{3}. Field的简化

{3}1. 由于字段没有什么参数,所以第一关联省去对“形参”的关联。

其中对“方法名”的关联,对于Field仅仅做了一半由于字段的settergetter命名是setFieldName(xxx)和getFieldName()。所以只要是给出了字段名setter和getter的名字就能构建出来。这样,对于不同类的不同字段FieldName被定义成String类型相关联,通用的setget就被设置为Field的方法

所以这里名义上关联字段名实际上关联的方法名

【举例】

//关联方法名的一半,另一半封装到field对象中   没有对形式参数进行关联

Field field =clazz.getField("country");

 

//setter操作

field.set(obj, "China");

 

//getter操作

Object o =field.get(obj);

{3}. Method的不能简化。因为Method是没有特殊的地方,所以遵循完整的双关联格式。

2.    反射代码书写 形式上的特点

反射含义的代码字面理解


 

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值