黑马程序员-Java基础-反射

第一讲 反射应用场景&特色函数

一、反射定义3d

动态的获取指定类以及动态的调用类中的内容。给程序使用者提供了一个能够本身定制功能的接口,提升了程序的扩展性。对象

二、实现方式blog

经过配置文件的方式,程序使用者在配置文件中设置自定义的类名,程序内部调用该配置文件,获取该类的字节码文件及类对象,进而调用类中的成员方法和成员变量,实现了成语与使用者的交互。接口

其中,实现接口的类由程序使用者本身定义。字符串

三、图解示例get

           

 

 

 

 

 

第二讲 获取字节码文件对象&建立类对象it

一、Class类ast

Class——用来描述字节码文件的类,反射的技术就是经过该类来实现的。class

该类中提供和获取类字节码文件对应类中的构造函数对象、通常方法对象、字段对象的方法。

二、获取字节码文件的对象的方式

方式一:经过Object类中的getClass()方法获取,须要经过类的对象调用。

示例以下:获取Person类中的字节码文件对象

Person p = new Person();——建立类对象

Class clazz = p.getClass();——经过Object中的方法getClass()获取字节码文件对象。

说明:这种方法须要明确具体的类,并建立该类的对象,比较麻烦。

方式二:任何数据类型都具有一个静态的属性”.class”,能够用类直接调用:Class clazz = Person.class;

说明:该方法相对于方式一更加简单,但仍是要明确类名和类中的静态成员,仍是不够扩展。

方式三:Class类中的forName(String className)方法,其中的className要完整,包括包名(如,cn.itcast.bean.Person)。

代码实现以下:

String className = “cn.itcast.bean.Person”;——这里的类型能够经过配置文件读取到,由程序使用者本身定义类,并将类型输入到配置文件指定位置,传入程序中。

Class clazz = forName(className);——程序经过从配置文件上获取到的类名来获取该类对应的字节码文件对象。

说明:只经过给定的类的字符串名称就能够获取该类,扩展性更强。

以上三种方式代码示例:

 

 

第三讲 获取构造函数&动态建立类对象

一、概述

要建立类对象就须要调用类的构造函数(类内部定义方法获取对象的状况除外),Class类中定义了获取类对象的方法newInstance(),该方法调用了类中的无参数构造函数;

代码实现以下:

 

二、调用类中有参数构造函数来建立类对象

Class类中的newInstance()方法只能调用类中的无参数构造函数,要想经过类中的有参数构造函数来建立类对象,就要先获取类中的有参数构造函数。

实现方法:

先获取类中带参数的构造函数对象(利用

getConstructor(String.class,int.class)方法),根据本身须要来肯定参数列表;

而后经过获取到的构造函数对象调用方法newInstance(String str,int i),来调用类中带参数构造函数来建立类对象,代码实现以下:

 

 

 

 

第四讲  获取类中的方法

一、概述

咱们获取到类的字节码文件对象后,能够经过该对象获取中通常方法的对象,而后用方法对象获取通常方法。

二、获取并调用通常方法

  • 获取字节文件对象;

Class clazz = Class.forName(className);

  • 根据方法名获取方法对象;

Method method = clazz.getMethod(methodName,String.class,int.class);

取空参数函数:clazz.getMethod(methodName,null)

  • 调用方法;

Object obj = clazz.newInstance();——需先建立类对象。

methods.invoke(obj,”zhangsan”,”23”);

调用静态方法:methods.invoke(null,”zhangsan”,”23”);——调用静态方法,不须要对象。

       总结:经过字节码文件对象来获取方法对象,经过方法类中的invoke()来调用方法。若是调用的是非静态方法,则invoke()实际参数中要有类对象;若,调用的是静态方法,则不须要类对象,用null代替。没有参数的地方,用null代替。

 

 

第五讲 获取字段&暴力访问

一、概述

Class类中定义了获取字段对象的方法,获取了字段对象,就能够用它来访问类中的字段(获取、设置等)。

二、获取并设置字段步骤

  • 获取字节码文件对象;——Class.forName()
  • 用字节码文件对象调用Class中的方法getField(fieldName)或

getDeclaredField(fieldName)来获取自定名称的字段对象;

getField(fieldName)——获取的是共有字段的对象;

getDeclaredField(fieldName)——获取的是因此字段的对象;

  • 设置字段;——field.set(obj,90);须要指定类对象。

说明:若为私有字段,此处设置字段值会失败,咱们能够经过暴力访问的方式,将访问权限检查取消,再设置字段的值。

三、暴力访问类中的私有成员——用AccessiableObject类

定义:AccessiableObject类是Field类、Method类、Constructor类的父类,该类中方法setAccessible()能够取消类中成员的权限检查,以使得Field类对象、Method类对象、Constructor类对象可以访问类中的私有字段、方法;

实现代码:

Field.setAccessible(true);——取消对字段的的权限访问,即暴力访问。

field.set(obj,90);——设置私有字段值。

 

说明:程序将成员声明成私有的,试想把该成员保护起来,因此通常不访问私有成员。

 

 

 

第六讲   反射应用案例

演示笔记本电脑使用USB接口示例:

需求:笔记本电脑调用接入USB接口的设备,要求不一样的设备执行不一样的方法。

思路

一、电脑须要使用一些外围设备,如鼠标、键盘、U盘等,为了提升扩展性,应该下降这些设备和电脑的耦合性,所以就须要引入接口的技术(无论接入什么设备,只要符合USB规则,就能够被电脑使用)。

二、然而,若是USB接口接入了新的设备,就须要修改原始代码,才能调用新的设备,这样很麻烦,所以,能够引入反射的技术,提供一个配置文件。

三、咱们只须要将接入设备的功能定义好,而且在配置文件中传入设备的信息,在不修改原代码的状况下,电脑也能使用接入的设备。

代码演示:

 

相关文章
相关标签/搜索