如何在 类 周围创建一个已存在但无法在 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 Order
和 AnotherOrder 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);
}
}
假设我的代码中已经有 2 个 类:
class SomeOrder {
String getOrderId() { return orderId; }
}
class AnotherOrder {
String getOrderId() { return orderId; }
}
如何围绕这两个 类 创建接口,即:
interface Order {
String getOrderId();
}
理想情况下,我会修改代码,使 SomOrder implements Order
和 AnotherOrder 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);
}
}