程序员Android开发移动开发

花一杯茶的时间,学会Java反射(实用篇)

2016-10-20  本文已影响204人  chenxuxu

前言

之前,我写了一篇关于java反射的使用——花一杯茶的时间,学会Java反射(基础篇),今天就拿一些实例和应用给大家看看如何在项目中用反射。

实例

反射可以提高代码的扩展性,低耦合,高内聚。就拿工厂模式来说。

  1. 首先是简单工厂模式,没有使用反射。

     /**
      * 动物接口
      * 
      * @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和类CatDogMain不改变,将工厂类修改成以下:

    /**
     * 动物工厂类
     * 
     * @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;
        }
    }

只要你的参数正确(记住是包名+类名),就可以获取到对应类的实例。

  1. 现在假设一种场景。有一个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方法就行了。

上一篇 下一篇

猜你喜欢

热点阅读