一、反射:程序可以访问、检测、修改它本身状态或行为的一种能力;反射机制允许程序在运行时获取任意一个类自身的定义信息;例如,可以实现动态创建类的对象、变更属性的内容或执行特定的方法功能。
反射是一类应用,它们能够自描述和自控制;也就是说,这类应用通过采用某种机制来实现对自己行为的描述和监测,并能根据自身行为的状态和结果调正或修改应用所描述行为的状态和相关的语义。
二、作用:
- 在运行时判断任意一个对象属性的类型;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的属性和方法;
- 在运行时调用任意一个对象的方法,甚至可以调用 private 方法;
三、反射机制相关API:
创建用于创建对象的基础实体类:
package com.sztxtech.reflectapi.entity;
import java.io.Serializable;
public class User extends Employee implements Serializable{
private static final long serialVersionUID = 1L;
private Integer userId;
private String username;
private Integer age;
private String sex;
// getter、setter 省略
}
package com.sztxtech.reflectapi.entity;
import java.io.Serializable;
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
private Integer custId;
private String custName;
private String company;
private String telephone;
private String job;
// getter、setter 省略
}
package com.sztxtech.reflectapi.entity;
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String deptId;
private String supervisor;
// getter、setter 省略
}
1. 使用反射,通过一个对象可以获取完整的包名和类名:
public class TestOne {
public static void main(String[] args) {
User user = new User();
Customer customer = new Customer();
// 通过对象获取完整的包名和类名
System.out.println(user.getClass()); //class com.sztxtech.reflectapi.entity.User
System.out.println(customer.getClass()); //class com.sztxtech.reflectapi.entity.Customer
System.out.println(user.getClass().getName()); //com.sztxtech.reflectapi.entity.User
System.out.println(customer.getClass().getName()); //com.sztxtech.reflectapi.entity.Customer
}
}
2. 使用反射,实例化Class类对象:
public class TestTwo {
public static void main(String[] args) throws ClassNotFoundException {
// 实例化Class类对象
Class<?> clazz1 = null;
Class<?> clazz2 = null;
Class<?> clazz3 = null;
clazz1 = Class.forName("com.sztxtech.reflectapi.entity.User");
clazz2 = new User().getClass();
clazz3 = User.class;
System.out.println(clazz1); //class com.sztxtech.reflectapi.entity.User
System.out.println("类名称:"+clazz1.getName()); //类名称:com.sztxtech.reflectapi.entity.User
System.out.println(clazz2); //class com.sztxtech.reflectapi.entity.User
System.out.println("类名称:"+clazz2.getName()); //类名称:com.sztxtech.reflectapi.entity.User
System.out.println(clazz3); //class com.sztxtech.reflectapi.entity.User
System.out.println("类名称:"+clazz3.getName()); //类名称:com.sztxtech.reflectapi.entity.User
}
}
3. 通过反射获取一个对象的父类与实现的接口:
为测试效果,随意自定义一个接口:
package com.sztxtech.reflectapi.inter;
public interface TestInterface {
}
修改User类,让其实现该接口:
package com.sztxtech.reflectapi.entity;
import java.io.Serializable;
import com.sztxtech.reflectapi.inter.TestInterface;
public class User extends Employee implements Serializable, TestInterface{
private static final long serialVersionUID = 1L;
private Integer userId;
private String username;
private Integer age;
private String sex;
// getter、setter 省略
}
测试主类:
public class TestThree {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.sztxtech.reflectapi.entity.User");
// 获取对象的父类
Class<?> parentClass = clazz.getSuperclass();
System.out.println("clazz的父类为:"+parentClass.getName());//clazz的父类为:com.sztxtech.reflectapi.entity.Employee
User user = new User();
Class<?> pClass = user.getClass().getSuperclass();
System.out.println("user的父类为:"+pClass.getName());//user的父类为:com.sztxtech.reflectapi.entity.Employee
Class<?> empPClass = user.getClass().getSuperclass().getSuperclass();
System.out.println("user父类的父类为:"+empPClass.getName());//user父类的父类为:java.lang.Object
// 获取实现的接口
Class<?> inters[] = clazz.getInterfaces();
System.out.println("clazz所实现的接口有:");
for (int i = 0; i < inters.length; i++) {
System.out.println(inters[i].getName());
}
}
}
// 以上测试程序运行结果如下:
clazz的父类为:com.sztxtech.reflectapi.entity.Employee
user的父类为:com.sztxtech.reflectapi.entity.Employee
user父类的父类为:java.lang.Object
clazz所实现的接口有:
java.io.Serializable
com.sztxtech.reflectapi.inter.TestInterface
4. 通过反射获取某个类的所有构造方法;通过反射机制实例化一个类的对象:
进一步修改User类 [ 为User类添加三个构造方法和toString方法,并且toString方法中同时获取了父类的属性 ]:
package com.sztxtech.reflectapi.entity;
import java.io.Serializable;
import com.sztxtech.reflectapi.inter.TestInterface;
public class User extends Employee implements Serializable, TestInterface{
private static final long serialVersionUID = 1L;
private Integer userId;
private String username;
private Integer age;
private String sex;
// getter、setter 省略
// 无参构造器
public User() {
super();
}
// 带参数构造器
public User(Integer userId, String username) {
super();
this.userId = userId;
this.username = username;
}
// 带参数构造器
public User(Integer userId, String username, Integer age, String sex) {
super();
this.userId = userId;
this.username = username;
this.age = age;
this.sex = sex;
}
// toString()方法
@Override
public String toString() {
return "User [userId=" + userId + ", username=" + username + ", age=" + age + ", sex=" + sex +
", deptId=" + super.getDeptId() + ", supervisor=" + super.getSupervisor() + "]";
}
}
测试主类:
public class TestFour {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> clazz = null;
clazz = Class.forName("com.sztxtech.reflectapi.entity.User");
// 第一种方式,实例化默认构造方法,调用setter方法进行赋值
User user = (User) clazz.newInstance();
user.setUserId(1107492);
user.setUsername("Jack");
user.setSex("Man");
user.setAge(26);
user.setDeptId(10);
user.setSupervisor(1123306);
System.out.println(user);
System.out.println("**************************************************************************************************");
// 第二种方式,获取全部的构造方法,使用构造方法赋值
Constructor<?> cons[] = clazz.getConstructors();
// 遍历出每个构造方法
for(int i=0; i<cons.length; i++){
Class<?> conParam[] = cons[i].getParameterTypes();
System.out.print("cons[" + i + "] (");
for (int j = 0; j < conParam.length; j++) {
if(j == conParam.length - 1){
System.out.print(conParam[j].getName());
}else{
System.out.print(conParam[j].getName() + ", ");
}
}
System.out.println(")");
if(conParam.length == 2){
// 通过两个参数的构造器实例化 user0 对象
User user0 = (User)cons[i].newInstance(1111, "James");
System.out.println("user0:"+user0);
}else if(conParam.length == 4){
// 通过四个参数的构造器实例化 user3 对象
User user2 = (User)cons[i].newInstance(2222, "Even", 28, "Man");
System.out.println("user2:"+user2);
}
System.out.println("----------------------------------------------------------------------------------------");
}
System.out.println("==================================================================================================");
}
}
// 以上程序的运行结果如下
User [userId=1107492, username=Jack, age=26, sex=Man, deptId=10, supervisor=1123306]
**************************************************************************************************
cons[0] (java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.String)
user2:User [userId=2222, username=Even, age=28, sex=Man, deptId=null, supervisor=null]
----------------------------------------------------------------------------------------
cons[1] ()
----------------------------------------------------------------------------------------
cons[2] (java.lang.Integer, java.lang.String)
user0:User [userId=1111, username=James, age=null, sex=null, deptId=null, supervisor=null]
----------------------------------------------------------------------------------------
==================================================================================================
5. 通过反射获取某个类的所有属性[ 包括所继承父类的属性、所实现接口的属性 ]
为配合测试,需要在Employee类、TestInterface接口中添加属性:
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Integer deptId;
private Integer supervisor;
// 新增属性
protected String telephone;
public String address;
public double salary;
String nativePlace;
// getter、setter 省略
}
package com.sztxtech.reflectapi.inter;
public interface TestInterface {
// 新增属性
static final String inter_property_111="111";
public double inter_property_222=222;
int inter_property_333=333;
}
测试主类:
public class TestFive {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> user = Class.forName("com.sztxtech.reflectapi.entity.User");
System.out.println("====================获取User类的所有属性相关信息====================");
Field[] field = user.getDeclaredFields(); // 获取User类的所有属性
for (int i = 0; i < field.length; i++) {
int mo = field[i].getModifiers();
String priv = Modifier.toString(mo);
// System.out.println(mo+" ==> "+priv);
Class<?> types = field[i].getType(); // 获取属性类型信息
System.out.println("属性访问权限:" + priv +
" || 属性数据类型:" + types.getName() +
" || 属性名称:" + field[i].getName() + ";");
}
System.out.println("================获取父类及所实现接口的所有属性相关信息================");
Field[] fields = user.getFields();
for (int i = 0; i < fields.length; i++) {
int mo = fields[i].getModifiers();
String priv = Modifier.toString(mo);
Class<?> types = fields[i].getType(); // 获取属性类型信息
System.out.println("属性访问权限:" + priv +
" || 属性数据类型:" + types.getName() +
" || 属性名称:" + fields[i].getName() + ";");
}
}
}
// 以上程序运行结果如下
====================获取User类的所有属性相关信息====================
属性访问权限:private static final || 属性数据类型:long || 属性名称:serialVersionUID;
属性访问权限:private || 属性数据类型:java.lang.Integer || 属性名称:userId;
属性访问权限:private || 属性数据类型:java.lang.String || 属性名称:username;
属性访问权限:private || 属性数据类型:java.lang.Integer || 属性名称:age;
属性访问权限:private || 属性数据类型:java.lang.String || 属性名称:sex;
====================获取父类及所实现接口的所有属性相关信息====================
属性访问权限:public static final || 属性数据类型:java.lang.String || 属性名称:inter_property_111;
属性访问权限:public static final || 属性数据类型:double || 属性名称:inter_property_222;
属性访问权限:public static final || 属性数据类型:int || 属性名称:inter_property_333;
属性访问权限:public || 属性数据类型:java.lang.String || 属性名称:address;
属性访问权限:public || 属性数据类型:double || 属性名称:salary;
从运行结果可以看出:
该方法( Field[] java.lang.Class.getFields() ) 获取某个类的父类及所实现接口的属性时,只能访问权限为 public 的属性;由 private、protected、default 修饰的属性均不能获取到;并且所有接口中定义的属性的访问权限都是 public static final 的,这也符合接口中定义属性的规则 (接口中只能有静态、不能被修改的成员变量,且必须赋初始值) 相吻合。
6. 通过反射获取某个类的全部方法信息
package com.sztxtech.reflectapi.reflecttest;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 通过反射获取某个类的全部方法信息;包括其所属类的父类的方法信息
*
*/
public class TestSix {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.sztxtech.reflectapi.entity.User");
// 获取clazz对象所有的方法[包括其所属类的父类的方法]
Method method[] = clazz.getMethods();
for (int i = 0; i < method.length; i++) {
// 获取方法的返回值
Class<?> returnType = method[i].getReturnType();
// 获取方法的参数
Class<?> param[] = method[i].getParameterTypes();
// 获取方法的访问权限
int temp = method[i].getModifiers();
System.out.println("----------------------------------------------------");
System.out.print(Modifier.toString(temp)+"; ||");
System.out.print(returnType.getName()+"; ||");
System.out.println(method[i].getName()+"; ||");
System.out.print("(");
for(int j=0; j<param.length; j++){
System.out.print("参数:" + param[j].getName()+" arg" + j);
if(j < param.length - 1){
System.out.print(", ");
}
}
// 获取方法抛出的异常信息
Class<?> exce[] = method[i].getExceptionTypes();
if(exce.length > 0){
System.out.print(") throws ");
for(int k=0; k<exce.length; k++){
System.out.print(exce[k].getName() + " ");
if(k < exce.length - 1){
System.out.print(", ");
}
}
}else{
System.out.print(")");
}
System.out.println();
}
}
}
7. 通过反射机制调用某个类的方法
新建提供方法的类:MethodProviderClass
package com.sztxtech.reflectapi.simple;
public class MethodProviderClass {
private void method11(){
System.out.println("方法提供类提供的第一个方法,私有的(private)方法...");
}
protected void method22(){
System.out.println("方法提供类提供的第二个方法,受保护的(protected)方法...");
}
void method33(){
System.out.println("方法提供类提供的第三个方法,默认权限的(default)方法...");
}
public void method44(){
System.out.println("方法提供类提供的第四个方法,公开的(public)方法...");
}
}
测试主类:
package com.sztxtech.reflectapi.reflecttest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 通过反射机制调用某个类的方法
*
*/
public class TestSeven {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class<?> clazz = Class.forName("com.sztxtech.reflectapi.simple.MethodProviderClass");
// 通过反射机制,分别调用 MethodProviderClass 类中的方法
// Method method1 = clazz.getMethod("method11"); // Exception in thread "main" java.lang.NoSuchMethodException: com.sztxtech.reflectapi.simple.MethodProviderClass.method11()
// Method method2 = clazz.getMethod("method22"); // Exception in thread "main" java.lang.NoSuchMethodException: com.sztxtech.reflectapi.simple.MethodProviderClass.method22()
// Method method3 = clazz.getMethod("method33"); // Exception in thread "main" java.lang.NoSuchMethodException: com.sztxtech.reflectapi.simple.MethodProviderClass.method33()
Method method4 = clazz.getMethod("method44");
method4.invoke(clazz.newInstance()); // 方法提供类提供的第四个方法,公开的(public)方法...
Method method5 = clazz.getMethod("method55", String.class, int.class);
method5.invoke(clazz.newInstance(), "Gavin Lee", 26); // 方法提供类提供的第五个方法,公开的(public)、带参数的方法......!!! method55 接收到的参数:name=Gavin Lee; age=26
}
}
8. 通过反射机制,操作某个类的属性
在 MethodProviderClass 类中添加不同访问权限的四个属性如下:
public class MethodProviderClass {
private String propertyOne;
protected String propertyTwo;
String propertyThree;
public String propertyFour;
// 之前已有的其他内容省略
}
测试主类:
package com.sztxtech.reflectapi.reflecttest;
import java.lang.reflect.Field;
/**
* 通过反射机制,操作某个类的属性
*
*/
public class TestEighth {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException, NoSuchFieldException, SecurityException {
Class<?> clazz = Class.forName("com.sztxtech.reflectapi.simple.MethodProviderClass");
// 创建MethodProviderClass类型的实例
Object obj = clazz.newInstance();
// 通过反射分别获取MethodProviderClass类的所有属性
Field fieldOne = clazz.getDeclaredField("propertyOne");
Field fieldTwo = clazz.getDeclaredField("propertyTwo");
Field fieldThree = clazz.getDeclaredField("propertyThree");
Field fieldFour = clazz.getDeclaredField("propertyFour");
fieldOne.setAccessible(true); //设置反射的对象取消Java语言访问检查
fieldOne.set(obj, "第一个参数【private修饰】"); // 为fieldOne属性赋值
System.out.println(fieldOne.get(obj));
fieldTwo.setAccessible(true); //设置反射的对象取消Java语言访问检查
fieldTwo.set(obj, "第二个参数【protected修饰】"); // 为fieldTwo属性赋值
System.out.println(fieldTwo.get(obj));
fieldThree.setAccessible(true); //设置反射的对象取消Java语言访问检查
fieldThree.set(obj, "第三个参数【默认访问权限】"); // 为fieldThree属性赋值
System.out.println(fieldThree.get(obj));
fieldFour.set(obj, "第四个参数【public修饰】"); // 为fieldFour属性赋值
System.out.println(fieldFour.get(obj));
}
}
// 以上程序运行结果如下:
第一个参数【private修饰】
第二个参数【protected修饰】
第三个参数【默认访问权限】
第四个参数【public修饰】
9. 反射机制的动态代理
说明:以下小案例只注重反射机制和动态代理的使用,而不注重业务逻辑。
步骤一:定义接口
package com.sztxtech.reflectapi.inter;
/**
* 定义接口
*
*/
public interface Subject {
public String getInfo(String username, String password);
public Object findUserInfomation(String username, String pwd) throws Exception;
}
步骤二:定义接口实现类
package com.sztxtech.reflectapi.inter.impl;
import java.lang.reflect.Field;
import com.sztxtech.reflectapi.entity.User;
import com.sztxtech.reflectapi.inter.Subject;
/**
* 定义接口实现类
*
*/
public class SubjectImpl implements Subject {
@Override
public String getInfo(String username, String password) {
// TODO Auto-generated method stub
return "username=" + username + "; password=" + password;
}
@Override
public User findUserInfomation(String username, String pwd) throws Exception {
// TODO Auto-generated method stub
User user = new User();
Class<?> clazz = Class.forName("com.sztxtech.reflectapi.entity.User");
Object obj = clazz.newInstance();
Field userId = clazz.getDeclaredField("userId");
Field userName = clazz.getDeclaredField("username");
Field age = clazz.getDeclaredField("age");
Field sex = clazz.getDeclaredField("sex");
userId.setAccessible(true);
userId.set(obj, 1107492);
user.setUserId(1107492);
userName.setAccessible(true);
userName.set(obj, username);
user.setUsername(username);
age.setAccessible(true);
age.set(obj, 26);
user.setAge(26);
sex.setAccessible(true);
sex.set(obj, "Man");
user.setSex("Man");
user.setSupervisor(1123362);
user.setDeptId(1111);
return user;
}
}
步骤三:创建动态代理类
package com.sztxtech.reflectapi.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 创建动态代理类
*
*/
public class ProxyHandler implements InvocationHandler {
private Object obj = null;
public ProxyHandler(Object obj) {
super();
this.obj = obj;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object temp = method.invoke(obj, args);
return temp;
}
}
步骤四:测试主类
package com.sztxtech.reflectapi.reflecttest;
import java.lang.reflect.Proxy;
import com.sztxtech.reflectapi.entity.User;
import com.sztxtech.reflectapi.inter.Subject;
import com.sztxtech.reflectapi.inter.impl.SubjectImpl;
import com.sztxtech.reflectapi.proxy.ProxyHandler;
/**
* 反射机制的动态代理
*
*/
public class TestNine {
public static void main(String[] args) throws Exception {
Subject subject = new SubjectImpl();
ProxyHandler proxyHandler = new ProxyHandler(subject);
Subject sub = (Subject) Proxy.newProxyInstance(proxyHandler.getClass().getClassLoader(), subject.getClass().getInterfaces(), proxyHandler);
String result = sub.getInfo("Gavin Lee", "123456");
User user = (User) sub.findUserInfomation("Jack", "1234");
System.out.println(result);
System.out.println(user);
}
}
运行结果:
username=Gavin Lee; password=123456
User [userId=1107492, username=Jack, age=26, sex=Man, deptId=1111, supervisor=1123362]
四、反射机制的应用实例
1. 在泛型为 Integer 的 ArrayList 中存放任意类型的对象;
package com.sztxtech.reflectapi.reflectapply;
import java.lang.reflect.Method;
import java.util.ArrayList;
import com.sztxtech.reflectapi.entity.User;
/**
* 反射机制的应用实例1:
* 在泛型为 Integer 的 ArrayList 中存放任意类型的对象;
*/
public class TestApplyOne {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ArrayList<Integer> list = new ArrayList<>();
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list, "Java");
method.invoke(list, "Spring");
method.invoke(list, 123);
method.invoke(list, 2323.66);
method.invoke(list, new User());
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
2. 通过反射获取并修改数组的信息;
package com.sztxtech.reflectapi.reflectapply;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
/**
* 反射机制的应用实例2:
* 通过反射获取并修改数组的信息;
*
*/
public class TestApplyTwo {
public static void main(String[] args) {
int[] array = {111, 222, 333, 444, 555};
// 获取数组的元素数据类型
Class<?> clazz = array.getClass().getComponentType();
System.out.println("数组类型为:"+clazz.getName()); // 数组类型为:int
System.out.println(Modifier.toString(clazz.getModifiers())); // public abstract final
System.out.println("数组长度为:"+Array.getLength(array)); // 数组长度为:5
System.out.println("数组的第二个元素:"+Array.get(array, 1)); // 数组的第二个元素:222
Array.set(array, 1, 8888);
System.out.println("修改后数组的第二个元素为:"+Array.get(array, 1)); // 修改后数组的第二个元素为:8888
}
}
3. 通过反射机制修改数组的大小;
package com.sztxtech.reflectapi.reflectapply;
import java.lang.reflect.Array;
/**
* 反射机制的应用实例3:
* 通过反射机制修改数组的大小;
*/
public class TestApplyThree {
public static void main(String[] args) {
int[] arrayOne = {11, 22, 33, 44, 55, 66, 77, 88, 99, 101};
int[] arrayTwo = (int[]) modifyArray(arrayOne, 15);
printArray(arrayTwo);
String[] strArrOne = {"aa", "bb", "cc", "dd", "ee"};
String[] strArrTwo = (String[]) modifyArray(strArrOne, 10);
printArray(strArrTwo);
}
/**
* 修改数组大小
* @param arrayOne: 要修改的数组
* @param len: 要将arrayOne的长度修改为 len
* @return : 返回修改后的数组
*/
private static Object modifyArray(Object arrayOne, int len) {
// 获取要修改的数组的元素数据类型
Class<?> clazz = arrayOne.getClass().getComponentType();
// 新建数组:元素数据类型为 clazz;长度为 len;
Object newArr = Array.newInstance(clazz, len);
// 获取要修改的数组的长度
int length = Array.getLength(arrayOne);
/* 将源数组中的元素复制到新创建的数组中:
* arrayOne:源数组[要进行修改的数组]
* 0:从源数组中复制元素的起始位置(下标)
* newArr:目标数组[新创建的数组]
* 0:向目标数组中粘贴元素的起始位置(下标)
* length:源数组中复制的元素的长度
*/
System.arraycopy(arrayOne, 0, newArr, 0, length);
return newArr;
}
/**
* 遍历数组元素,并在控制台输出结果
* @param obj: 要遍历的数组
*/
public static void printArray(Object obj){
Class<?> clazz = obj.getClass();
if(!clazz.isArray()){
return;
}
System.out.println("要遍历的数组的长度为:"+ Array.getLength(obj));
for (int i = 0; i < Array.getLength(obj); i++) {
System.out.print(Array.get(obj, i) + " ");
}
System.out.println();
}
}
4. 将反射机制应用于工厂模式;
新建接口:Animal
package com.sztxtech.reflectapi.inter;
/**
* 动物接口
*/
public interface Animal {
public abstract void snarl();
public abstract void runing();
public abstract void sleeping();
}
新建实现类:Lion、Tiger
package com.sztxtech.reflectapi.inter.impl;
import com.sztxtech.reflectapi.inter.Animal;
/**
* 狮子类
*/
public class Lion implements Animal {
@Override
public void snarl() {
// TODO Auto-generated method stub
System.out.println("狮子在咆哮...");
}
@Override
public void runing() {
// TODO Auto-generated method stub
System.out.println("狮子在狂奔...");
}
@Override
public void sleeping() {
// TODO Auto-generated method stub
System.out.println("狮子在睡觉...");
}
}
package com.sztxtech.reflectapi.inter.impl;
import com.sztxtech.reflectapi.inter.Animal;
/**
* 老虎类
*/
public class Tiger implements Animal {
@Override
public void snarl() {
// TODO Auto-generated method stub
System.out.println("老虎在咆哮...");
}
@Override
public void runing() {
// TODO Auto-generated method stub
System.out.println("老虎在狂奔...");
}
@Override
public void sleeping() {
// TODO Auto-generated method stub
System.out.println("老虎在睡觉...");
}
}
新建工厂类:AnimalFactory
package com.sztxtech.reflectapi.factory;
import com.sztxtech.reflectapi.inter.Animal;
/**
* 动物工厂类
*/
public class AnimalFactory {
public static Animal getInstacne(String className){
Animal animal = null;
try {
animal = (Animal) Class.forName(className).newInstance();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return animal;
}
}
测试类:
package com.sztxtech.reflectapi.reflectapply;
import com.sztxtech.reflectapi.factory.AnimalFactory;
import com.sztxtech.reflectapi.inter.Animal;
/**
* 反射机制的应用实例4:
* 将反射机制应用于工厂模式;
*/
public class TestApplyFour {
public static void main(String[] args) {
Animal lion = AnimalFactory.getInstacne("com.sztxtech.reflectapi.inter.impl.Lion");
Animal tiger = AnimalFactory.getInstacne("com.sztxtech.reflectapi.inter.impl.Tiger");
lion.snarl();
tiger.runing();
}
}
对于普通的工厂模式,当我们在添加一个字类的时候,就需要对应的修改工厂类。当需要添加很多子类的时候,就会变得很麻烦;我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。