前言
之前,我寫了一篇關于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
方法就行了。