如何在Java中以编程方式执行功能检测?

尼克·格莱利

我想编写一个Java框架,该框架支持JRE7作为基线,但是JRE8如果在JRE8(向上兼容?)的上下文中运行,则可以利用这些功能

(或者也许我有这个倒退……即JRE8是基线,但会优雅地下降以支持JRE7)。

Java是否提供执行此操作的方法?

我的尝试/示例:

我以为我可以以与javascript特征检测类似的方式解决此问题,我可以以编程方式测试我的Java8方法的存在(如果存在)以编程方式调用它,否则回退到Java7库。

海事组织这是一个非常艰巨的做法。如果此“功能切换/检测”可以由Java Runtime Environment/处理,那就太好了Java Compiler这可能吗,还是我正在服用疯狂药丸?

免责声明:我尚未解决编译问题,这将排除该解决方案的实用性(如果使用进行编译Java7,则无法添加-parameters到已编译的类中)。

public class Index {

    void tellme(String yourname) {
        /* ... */
    }

    public static void main(String[] args) throws Exception {
        Method tellme = Index.class.getDeclaredMethod("tellme", String.class);
        Method java8Params = null;
        try {
            java8Params = Method.class.getMethod("getParameters");
        } catch (NoSuchMethodException t) { /* ignore */ }
        if (java8Params != null) {
            // java 1.8 !!
            Object param = ((Object[]) java8Params.invoke(tellme))[0];
            System.out.printf("(java8) %s %s(%s %s){/*...*/}",
                    tellme.getReturnType(),
                    tellme.getName(),
                    param.getClass().getMethod("getType").invoke(param),
                    param.getClass().getMethod("getName").invoke(param));
        } else {
            // java 1.7 ...
            System.out.printf("(java7) %s %s(%s %s){/*...*/}",
                    tellme.getReturnType(),
                    tellme.getName(),
                    tellme.getParameterTypes()[0].getName(),
                    "arg0");
        }
    }
}
霍尔格

首先,使用反射来确保您的通用代码和可选API之间没有代码依赖性是正确的。由于在何时解析类和成员引用方面存在不同的策略,因此碰巧在一个JVM上起作用的非反射型惰性创建可能在另一个JVM上失败。

但这带来了一个问题,当必须通过反射对每个API的用法进行编码时,尤其是在您松散编译时检查时,某些操作难以实现,并且运行时性能也可能会受到影响。

通用的解决方案是使用Java从一开始就提供的OO技术。创建interfaceabstract class定义要素。实现Java 8解决方案和Java 7后备。在应用程序初始化期间或首次使用该功能时,您需要进行一次反思性检查,以确保最佳解决方案所依赖的功能是否可用,如果有,则实例化最佳实现,否则实例化后备。从那时起,您就可以像普通对象一样通过接口使用实现。

在简单的情况下,您可以将类的数量减少为两个,定义功能并提供回退行为的基类,以及专门的子类,用其专门的子类覆盖实现。

将Java 8实现保留在单独的源文件夹中,并使用Java 8编译器对其进行编译。其他代码将使用Java 7编译器进行编译,以确保不依赖Java 8实现。

通用Java 7兼容代码:

import java.lang.reflect.Method;

public class Index {
  static final MethodDescription DESC_ACCESSOR;
  static {
    MethodDescription md;
    try {
      Method.class.getMethod("getParameters");// test JRE feature
      // instantiate specialized solution
      md=(MethodDescription) Class.forName("MethodDescriptionJ8").newInstance();
    } catch(ReflectiveOperationException|LinkageError ex) {
      md=new MethodDescription(); // J7 fall-back
    }
    DESC_ACCESSOR=md;
  }

  void tellme(String yourname) {
      /* ... */
  }

  public static void main(String[] args) throws Exception {
      Method tellme = Index.class.getDeclaredMethod("tellme", String.class);
      String desc=DESC_ACCESSOR.get(tellme);
      System.out.println(desc);
  }
}
class MethodDescription {// base class defining application specific feature
    public String get(Method tellme) {// and providing fall-back implementation
      return String.format("(java7) %s %s(%s %s){/*...*/}",
          tellme.getReturnType(),
          tellme.getName(),
          tellme.getParameterTypes()[0].getName(),
          "arg0");
    }
}

使用Java 8单独编译:

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MethodDescriptionJ8 extends MethodDescription {
    @Override
    public String get(Method tellme) {
      Parameter param = tellme.getParameters()[0];
      return String.format("(java8) %s %s(%s %s){/*...*/}",
                    tellme.getReturnType(),
                    tellme.getName(),
                    param.getType(),
                    param.getName());
    }
}

但是请注意,关于此特定功能,结果可能令人失望。仅当自省类使用带有标志的Java 8编译时,参数名称才可用-parameters因此,即使在运行时使用Java 8方法,检查Java 7兼容类也不会为您提供参数名称。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在SwiftUI ScrollView中以编程方式检测滚动方向

来自分类Dev

如何在UIImagePickerController(相机)中以编程方式触发“完成”功能?

来自分类Dev

如何在Visual Studio中以编程方式执行“转到定义”?

来自分类Dev

如何在Spring 3中以编程方式执行注销

来自分类Dev

Java 1.7中的编程功能方式

来自分类Dev

如何在Java中以编程方式创建xml结构

来自分类Dev

如何在Java中以编程方式访问多维数组?

来自分类Dev

如何在Android中以编程方式检测移动设备制造商并进行建模?

来自分类Dev

如何在Android中以编程方式检测两次按下设备电源按钮

来自分类Dev

如何在Drupal 7中以编程方式设置具有OR功能的条件字段

来自分类Dev

如何在Drupal 7中以编程方式设置具有OR功能的条件字段

来自分类Dev

如何在MATLAB编辑器中以编程方式执行“折叠全折叠”?

来自分类Dev

如何在C#中以编程方式执行方法重载解析?

来自分类Dev

如何在Android最新版本中以编程方式执行UiAutomator测试用例

来自分类Dev

如何在Windows上以编程方式执行ping测试?

来自分类Dev

如何在应用商店中检测MobileFirst iOS应用的新版本并以编程方式直接更新?

来自分类Dev

如何以编程方式在android中自动执行触摸

来自分类Dev

如何在xml布局中对齐弯曲的图像?是否可以在Java中以编程方式对齐?

来自分类Dev

如何在32位或64位配置中以编程方式运行ANY CPU .NET可执行文件?

来自分类Dev

如何在32位或64位配置中以编程方式运行ANY CPU .NET可执行文件?

来自分类Dev

如何在Java中以编程方式设置闪光布局的持续时间?

来自分类Dev

如何在Java中以编程方式检查是否在向导页面上按下了帮助按钮

来自分类Dev

如何在java类中以编程方式使用<merge>标签而不在android中使用xml布局?

来自分类Dev

如何以编程方式检测屏幕撕裂?

来自分类Dev

如何以编程方式检测用户登录?

来自分类Dev

如何以编程方式检测屏幕撕裂?

来自分类Dev

如何在pygame中停止执行功能

来自分类Dev

UIView中的UIScrollView:以编程方式检测滚动

来自分类Dev

如何在Android中以编程方式更新Dropbox中的记录?

Related 相关文章

  1. 1

    如何在SwiftUI ScrollView中以编程方式检测滚动方向

  2. 2

    如何在UIImagePickerController(相机)中以编程方式触发“完成”功能?

  3. 3

    如何在Visual Studio中以编程方式执行“转到定义”?

  4. 4

    如何在Spring 3中以编程方式执行注销

  5. 5

    Java 1.7中的编程功能方式

  6. 6

    如何在Java中以编程方式创建xml结构

  7. 7

    如何在Java中以编程方式访问多维数组?

  8. 8

    如何在Android中以编程方式检测移动设备制造商并进行建模?

  9. 9

    如何在Android中以编程方式检测两次按下设备电源按钮

  10. 10

    如何在Drupal 7中以编程方式设置具有OR功能的条件字段

  11. 11

    如何在Drupal 7中以编程方式设置具有OR功能的条件字段

  12. 12

    如何在MATLAB编辑器中以编程方式执行“折叠全折叠”?

  13. 13

    如何在C#中以编程方式执行方法重载解析?

  14. 14

    如何在Android最新版本中以编程方式执行UiAutomator测试用例

  15. 15

    如何在Windows上以编程方式执行ping测试?

  16. 16

    如何在应用商店中检测MobileFirst iOS应用的新版本并以编程方式直接更新?

  17. 17

    如何以编程方式在android中自动执行触摸

  18. 18

    如何在xml布局中对齐弯曲的图像?是否可以在Java中以编程方式对齐?

  19. 19

    如何在32位或64位配置中以编程方式运行ANY CPU .NET可执行文件?

  20. 20

    如何在32位或64位配置中以编程方式运行ANY CPU .NET可执行文件?

  21. 21

    如何在Java中以编程方式设置闪光布局的持续时间?

  22. 22

    如何在Java中以编程方式检查是否在向导页面上按下了帮助按钮

  23. 23

    如何在java类中以编程方式使用<merge>标签而不在android中使用xml布局?

  24. 24

    如何以编程方式检测屏幕撕裂?

  25. 25

    如何以编程方式检测用户登录?

  26. 26

    如何以编程方式检测屏幕撕裂?

  27. 27

    如何在pygame中停止执行功能

  28. 28

    UIView中的UIScrollView:以编程方式检测滚动

  29. 29

    如何在Android中以编程方式更新Dropbox中的记录?

热门标签

归档