【问题标题】:Java Reflection: Call abstract interface methods without instantiationJava反射:调用抽象接口方法而不实例化
【发布时间】:2018-11-06 20:58:06
【问题描述】:

我目前在使用反射将现有 Piketec TPT Java API (http://javadoc.jenkins.io/plugin/piketec-tpt/com/piketec/tpt/api/package-summary.html) 集成到 Java 项目中时遇到问题。

TPT Api 提供了一个名为“TptApi”的接口,其中包含几个抽象方法,用于访问 TPT 项目。

我已经集成了其他 API,例如 Dox4j-API,其中一个类实例被用作调用目标。显然,这不是从接口访问方法的正确方法。

我的目标是从 TptApi 接口 (http://javadoc.jenkins.io/plugin/piketec-tpt/com/piketec/tpt/api/TptApi.html#openProject-java.io.File-) 访问方法“OpenResult openProject(File f)”。

我的代码:

ClassLoader cl = new URLClassLoader(...);
Map c = new HashMap();

File file = new File("test.prj");

c.put("TptApi", cl.loadClass("com.piketec.tpt.api.TptApi"));
c.put("OpenResult", cl.loadClass("com.piketec.tpt.api.OpenResult"));

//The way I did it with 'normal' classes, not applicable with the interface:
//Object target = ((Class) c.get("TptApi")).newInstance();

OpenResult or = (OpenResult)((Class) c.get("TptApi")).getMethod("openProject", new Class[]{File.class}).invoke(target, new Object[]{_file});

那么如何通过反射访问抽象接口方法呢?

【问题讨论】:

  • 使用来自 java.lang.reflect 的类 Method 的 method.invoke()。例如类 clazz = Something.class;方法[] 方法 = clazz.getDeclaredMethods(); for(方法方法:方法){ System.out.println(method.invoke()); }
  • 要执行的方法必须是具体的,而不是抽象的。这意味着您需要给它一个具体类的实例,该实例提供抽象方法的实现。也许您需要创建一个代理...?否则,您期望的行为是什么?
  • @gaurav:我使用invoke方法,但是不知道应该使用什么调用目标,因为我无法实例化接口。
  • '显然,这不是从接口访问方法的正确方式':垃圾。抽象接口方法需要一个实例。
  • @ErnestKiwele:收到您的回复后,我已联系工具支持人员,仍在等待回复。

标签: java reflection interface


【解决方案1】:

我最初的帖子并没有假设 TPT 不是使用 API 所必需的。确实如此。如何在TPT中启用API的方式有据可查,您发布的两行代码也可以。我描述的问题是使用 Java 反射访问 API。对于其他 API,我可以通过使用“newInstance”来访问该工具来做到这一点。使用TPT,对应的API对象是一个接口而不是一个类,所以没有办法实例化它。因此我想知道如何通过反射访问这个特定的 API。

【讨论】:

    【解决方案2】:

    我只是偶然发现了这个问题,所以即使它有点过时也让我回答一下。我在您的 cmets 中读到您假设您不需要 TPT 工具本身来使用 API。那是完全错误的。 API 只是一种通过 RMI 与开放 TPT 实例进行通信的方式。要连接到 TPT,TPT 实例必须启用 RMI,并且您必须知道可配置的端口和绑定名称。您可以在“TPT API”下的首选项中执行此操作,或者使用命令行参数“--apiPort”和“--apiBindingName”启动TPT。现在您可以使用这两行代码获取 TptApi 实例:

    Registry registry = LocateRegistry.getRegistry(HOST, PORT); // get Server/RMI-Registry
    TptApi remoteApi = (TptApi)registry.lookup(BINDING_NAME); // get TPT-API
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多