前言
之前,我写了一篇关于java反射的使用——花一杯茶的时间,学会Java反射(基础篇),今天就拿一些实例和应用给大家看看如何在项目中用反射。
实例
反射可以提高代码的扩展性,低耦合,高内聚。就拿工厂模式来说。
-
首先是简单工厂模式,没有使用反射。
/** * 动物接口 * * @author chenjunxu * */ public interface IAnimal { /** * 品种 */ public void kind(); } /** * 猫类 * * @author chenjunxu * */ public class Cat implements IAnimal { @Override public void kind() { System.out.println("I am cat!"); } } /** * 狗类 * * @author chenjunxu * */ public class Dog implements IAnimal { @Override public void kind() { System.out.println("I am dog!"); } } /** * 动物工厂类 * * @author chenjunxu * */ public class AnimalFactory { /** * 根据名称获取动物的实例 * * @param className * @return */ public static IAnimal chooseAnimal(String className) { if (className.equalsIgnoreCase("Dog")) { return new Dog(); } else if (className.equalsIgnoreCase("Cat")) { return new Cat(); } return null; } } /** * 主类 * * @author chenjunxu * */ public class Main { public static void main(String[] args) { IAnimal animal = AnimalFactory.chooseAnimal("Cat"); if (null != animal) { animal.kind(); } else { System.out.println("没有此动物!"); } } }
假设我们要新增一个动物:mouse。那么我们需要新建一个mouse类,然后在AnimalFactory工厂类中,加多一个if...else...
的判断。假设需要添加十多个动物呢?大家也知道,if...else...
用的越多,可能代码的可读性就越差,而且容易出错。
那么能不能每次添加一个新的动物类,然后不需要修改工厂类呢?答案就是反射。
接口IAnimal
和类Cat
、Dog
、Main
不改变,将工厂类修改成以下:
/**
* 动物工厂类
*
* @author chenjunxu
*
*/
public class AnimalFactory {
/**
* 根据动物类名获取动物的实例
*
* @param className(包名+类名)
* @return
*/
public static IAnimal chooseAnimal(String className) {
try {
Class<?> clazz = Class.forName(className);
return (IAnimal) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
只要你的参数正确(记住是包名+类名),就可以获取到对应类的实例。
-
现在假设一种场景。有一个APP的通用框架,可以用来做多种多样的APP。现在,有一些APP需要分享功能,有一些不需要分享功能。那我们最好以插件的形式,将分享功能封装成jar包或者library。
分享的jar包(分享库):package com.share.lib; /** * 分享库的分享类 * * @author chenjunxu * */ public class ShareLib { /** * 显示分享框 * * @param content */ public static void showShareDialog(String content) { System.out.println(content); } }
工具类:调用分享库ShareLib的分享方法:
package com.share.demo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 分享工具类
*
* @author chenjunxu
*
*/
public class ShareUtils {
/**
* 分享
*
* @param content
* 分享内容
*/
public static void share(String content) {
try {
Class<?> clazz = Class.forName("com.share.lib.ShareLib");
Method method = clazz.getMethod("showShareDialog", String.class);
method.invoke(null, content);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
主方法调用工具类的分享方法:
package com.share.demo;
/**
* 主类
*
* @author chenjunxu
*
*/
public class Main {
public static void main(String[] args) {
ShareUtils.share("我要分享内容!");
}
}
若是我们不需要使用分享功能,那就不需要修改工具类,直接不调用ShareUtils.share
方法就行了。