这段时间,在对接一个开源的版本时,发现由于依赖的开源版本api老是随着版本的变化而变化,导致代码经常需要修改,异常痛苦。

终于,在一个风和日丽的下午(五月末的广州异常暴晒),楼主下定决心要修掉这个大篓子。

在Internet寻找了很久,终于找到了解决方法,参考的文章在本文最后,感谢文章的作者。

使用java的反射机制,在代码里判断当前运行的是什么版本,然后调用相应的方法。

这样,代码就做到了自适应。

假设:

在自己的代码中,有这么一个工程。

Function.java

package chen.test.function;

public class Function{public static void test(String name ){
System.out.println(name);
System.out.println("test function have one input");
}
public static void test(String name , int id){
System.out.println(name);
System.out.println(id);
System.out.println("test function have two input");
}
}

对上面的Function.java程序编译出一个jar包,名为function.jar

这个Function类是我自己构造的,为了将Main.java程序编译通过,自己伪造一个方法即可。它有两个test方法,通过参数个数进行重载,但是实际的运行环境里,依赖的jar包中只有一个test方法,可能是两个输入参数的,也有可能是一个输入参数的。

请看Main.java程序怎么动态识别。

开发的程序中,依赖function.jar

Main.java

package chen.test.client;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import chen.test.function.Function; public class Main {
public static void main(String[] args){ Function aa = new Function(); tCl( aa );
}
/*
* 本程序是基于JDK1.7 编写,如果使用JDK1.6,那么下面有一些Exception JDK1.6 是不支持的
* 不支持的Exception 去除即可
*/
private static void tCl( Object obj ){
Class<?> classExec = obj.getClass();
Method exec = null;
try {
//如果运行的jar包支持两个参数的,就运行这个方法
//如果运行的jar包不支持两个参数,就进入catch 段,执行输入一个参数的方法
exec = classExec.getMethod("test", String.class, Integer.class);
try {
String re = (String) exec.invoke( classExec.newInstance(), "chenfool good", 123);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | InstantiationException e1) {
e1.printStackTrace();
} } catch (NoSuchMethodException | SecurityException e) {
try {
//运行中,依赖的jar包,不支持两个参数,导致进入此段代码
//运行只有一个输入参数的函数
exec = classExec.getMethod("test", String.class);
try {
String re = (String) exec.invoke( classExec.newInstance(), "chenfool good");
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | InstantiationException e1) {
e1.printStackTrace();
} } catch (NoSuchMethodException | SecurityException e1) {
e1.printStackTrace();
}
}
}
}

上面的Main.java程序虽然可以通过,但是方法中有一个缺陷,当Function类是不可构建的时,方法就不能通过了,它会报Function.class.getInterfaces()出错。

拥有私有构建函数的Function.java

package chen.test.function;

public class Function{
private Function(){ }
public static void test(String name ){
System.out.println(name);
System.out.println("test function have one input");
}
public static void test(String name , int id){
System.out.println(name);
System.out.println(id);
System.out.println("test function have two input");
}
}

这时,我们就要用别的方法来解决这个问题。

考虑,我们的目的就是判断当前运行的环境中,Function.test方法的输入参数是一个还是两个,所以我们使用getDeclaredMethod()方法,通过是否抛出异常来区分究竟是调用哪个test方法。

改进版本的Main.java程序

package chen.test.client;

import java.lang.reflect.Method;

import chen.test.function.Function;

public class Main {
public static void main(String[] args){ Class[] parameterTypes = new Class[2];
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
try {
//如果没有抛出异常,则证明此环境的Function类是调用两个参数的方法
//如果抛出异常,则调用一个输入参数的test方法
Method method = Function.class.getDeclaredMethod("test", parameterTypes);
Function.test("chenfool is great", 123);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
parameterTypes = new Class[1];
parameterTypes[0] = String.class;
Method method = null;
try {
//系统捕获异常,证明此运行环境调用的是一个输入参数的test方法
method = Function.class.getDeclaredMethod("test", parameterTypes);
Function.test("chenfool is good");
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} } } }

通过java的反射机制,我们就能动态的调用相应的方法,而无需因为依赖jar包的Api不兼容,导致开发多个程序来适配对应不同版本的Api,这样项目工程一旦变大,或者时间拉长,程序的维护成本会越来越高。

参考文章:

http://hi.baidu.com/vcxsloxuvibilyd/item/57b4da6bdcdc46106995e605

java 强大的反射机制的更多相关文章

  1. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  2. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  3. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  4. 黑马程序员——【Java高新技术】——反射机制

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 1.Java反射机制:是指“在运行状态中”,对于任意一个类,都能够知道这个类中的所有属性和方法: ...

  5. Java 中的反射机制

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...

  6. JAVA类型信息——反射机制

    JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...

  7. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  8. java基础之反射机制

    一.概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  9. 深入理解Java中的反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

随机推荐

  1. Intel processor brand names-Xeon,Core,Pentium,Celeron----Pentium

    http://en.wikipedia.org/wiki/Pentium Pentium From Wikipedia, the free encyclopedia     This article ...

  2. VS2013带来的&quot;新特性&quot;

    VS2013除了引入"Bootstrap"库以外,最大的变化就是.net Framework 4.5下面的都不支持了.也就是说,假设不把.net库升级成.net Framework ...

  3. java设计模式----真实世界的模式

    设计模式的定义: 模式是在某情境下,针对某问题的某种解决方案 反模式: 告诉你如何采用一个不好的解决方案解决一个问题 要点: 1.让设计模式自然而然地出现在你的设计中,而不是为了使用而使用 2.设计模 ...

  4. Android Camera系统深入理解

    1. Android Camera系统架构 http://blog.csdn.net/myarrow/article/details/8489674

  5. Spring Boot 动态数据源(多数据源自己主动切换)

    本文实现案例场景: 某系统除了须要从自己的主要数据库上读取和管理数据外.另一部分业务涉及到其它多个数据库,要求能够在不论什么方法上能够灵活指定详细要操作的数据库. 为了在开发中以最简单的方法使用,本文 ...

  6. delphi 中OutputDebugString 函数的妙用(使用DebugView或者Pascal Analyzer软件,在运行过程中就能监视和捕捉日志,而且通过网络就能监视)

    原文地址 https://www.peganza.com/delphi-and-outputdebugstring.html 曾经想要实时监控您的Delphi应用程序,并能够查看日志消息吗?当然,您始 ...

  7. 简说 call() 、apply() 、bind()

    对于这三个方法,我想一部分人还是比较陌生的. 所以今天来个简单的介绍~ 我们可以将call()和apply()看作是某个对象的方法,通过调用方法的形式来间接调用函数.call()和apply()的第一 ...

  8. JavaScript数组的某些操作(一)

    在软件开发的过程中JavaScript的编程在所难免.当中对数组的操作尤为常见,这里介绍一下和JavaScript数组相关的某些操作: 1.删除并返回数组的第一个元素--shift方法: <!D ...

  9. Duplicate Observed Data

    在翻看<重构-改善既有代码的设计>这本经典的书,书中就介绍了一个重构方法--Duplicate Observed Data 复制被监视数据的重构方法,使用这种方法能够使界面和对数据的操作隔 ...

  10. js 时间戳精确值的问题

    最近做一个多图上传的功能,通过name + 时间戳命名,结果发现时间戳竟然一样,一直以为是代码逻辑的问题,结果出错在时间戳的获取上了. 关于时间戳的获取方式: 1.Date.parse() var d ...