【问题标题】:Proxy a private interface代理私有接口
【发布时间】:2018-03-21 23:20:06
【问题描述】:

我确实需要用受保护的构造函数代理一个类的私有内部 java 接口。

我被现有的已编译 java 代码卡住了:

public class Foo {

  Foo() {}

  private interface Bar {
    void someMethod();
  }
}

并尝试编写此 clojure 代码:

(proxy [Foo$Bar] []
  (someMethod []
     ...))

但是编译这个会抛出java.lang.IllegalAccessError "proxy... cannot access its superinterface Foo$Bar"

有什么咒语可以解决这个问题吗?我很乐意使用任何必要的肮脏手段。

【问题讨论】:

  • 非常有趣的问题。我以为我是新的答案,但事实证明这是一个与我预期不同的解决方案。 :)
  • 您能详细说明为什么需要这样做吗?私有接口是封闭类的实现细节,所以我认为您不能使用代理以任何方式与现有代码进行交互。
  • 当然,我有一个应用程序必须覆盖 java.net.InetAddress 的名称解析逻辑。在 JDK8 上,我可以代理 sun.net.spi.nameservice.NameService 并使用反射将 InetAddress.nameServices 设置为我自己的 NameService 实现。我正在将此应用程序更新到 JDK10,他们使 NameService 接口成为 java.net.InetAddress 的私有内部接口。 (我意识到他们也提供了 hosts 文件选项,但我需要的名称解析逻辑无法在 hosts 文件中表达)。

标签: java clojure clojure-java-interop


【解决方案1】:

答案是extend原来的类,复制接口同时标记为public访问:

package demo;
public class Calc {
  Calc() {
    System.out.println(  "Calc() constructor");
  }
  private interface Adder {
    String doSomething();
  }
}

使用新的子类:

package demo;
public class CalcChild extends Calc {
  public CalcChild() {
    super();
    System.out.println("CalcChild(): super() - return ");
  }
  public interface Adder {
    String doSomething();
  }
  public void doBoo() {
    System.out.println("Boo!");
  }
}

还有proxy 代码:

 (let [adder      (proxy [demo.CalcChild$Adder] []
                    (doSomething [] "something"))
       calcChild  (demo.CalcChild.)]
   (.doSomething adder)
   (.doBoo calcChild))

结果:

Calc() constructor
CalcChild(): super() - return 
(.doSomething adder) => "something"
Boo!

更新:

我更新了答案,但还是有问题。即使我注释掉新的CalcChild() 构造函数,我也无法重现您的错误。

【讨论】:

  • 多么有创意。我试过了,但意识到我忘了在我原来的问题中指定 Foo 也有一个受保护的构造函数,所以当我尝试扩展它时,我得到“Foo()在 Foo 中不是公共的;不能从外部包访问” :-(。我会更新问题。
  • 好的,我想我知道发生了什么。我认为您的示例代码有效,因为 Calc 和 CalcChild 都在同一个包中。不幸的是,我无法访问包含我要扩展的类的包。这是 jdk10,所以如果我尝试重新创建相同的包层次结构,我会得到“错误:包存在于另一个模块中”。
猜你喜欢
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2019-08-22
  • 1970-01-01
  • 2022-12-04
  • 2013-06-05
相关资源
最近更新 更多