如何在 类 周围创建一个已存在但无法在 java 中修改的界面

how to create an interface around classes that already exist but cannot be modified in java

假设我的代码中已经有 2 个 类:

class SomeOrder {
  String getOrderId() { return orderId; }
}

class AnotherOrder {
  String getOrderId() { return orderId; }
}

如何围绕这两个 类 创建接口,即:

interface Order {
    String getOrderId();
}

理想情况下,我会修改代码,使 SomOrder implements OrderAnotherOrder implements Order 但这里的问题是它们属于我无法控制或编辑的包(即它们来自外部 jar ).

我的算法目前是这样的:

void sorter(List<SomeOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

void sorter(List<AnotherOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

用一个界面我可以写:

void sorter(List<Order> orders) {
        ... <custom sort logic> ...
        order.getOrderId();
}

您可以使用适配器 类:

class SomeOrderAdapter implements Order {
    private SomeOrder delegate;

    @Override
    public String getOrderId() {
        return delegate.getOrderId();
    }
}

AnotherOrder 类似。

因为你的界面是一个函数式界面,你可以定义映射到这个新的 Order 界面的函数,我为每个不同的 class:[=14= 引用 getOrderId 方法]

private Order wrap(SomeOrder obj) {
    return obj::getOrderId;
}

private Order wrap(AnotherOrder obj) {
    return obj::getOrderId;
}

一个调用它的例子:

private void test() {
    List<Order> orders = Arrays.asList(
        wrap(new SomeOrder()),
        wrap(new AnotherOrder())
    );
    sorter(orders);
}

创建一个 Proxy 环绕实现您需要的接口的实例。代理只是用相同的参数调用实例的方法。

public class Proxied<T> implements InvocationHandler {
  private final T wrapped;

  public Proxied(T wrapped) {
    this.wrapped = Objects.requireNonNull(wrapped);
  }

  public T getWrapped() {
    return wrapped;
  }

  public <I> Class<I> proxy(Class<I> interfaceClass) {
    @SuppressWarnings("unchecked")
    Class<I> proxyClass = (Class<I>)  Proxy.getProxyClass(getClass().getClassLoader(), interfaceClass);
    return proxyClass;
  }

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    return method.invoke(wrapped, args);
  }
}