因此,假设我有一个名为Users的类,该类具有一个名为name的私有变量和一个只返回name变量的公共getter方法,那么我该如何做,以便该getter为该类的所有实例返回name +“ test”可以访问用户类?
最佳答案
好吧,有几种方法可以用Java来做到这一点……
子类
首先,您可以扩展Users类并重写getter方法,如下所示:
public class TestUser extends User {
@Override
public String getName() { return super.getName() + "test"; }
}
然后,可以通过User类引用TestUser实例,并调用getName方法以使用新行为:
User tu = new TestUser("username");tu.getName(); // should return "usernametest"
动态代理
现在...如果由于某种原因无法扩展您的类并且无法接触现有的User类,那么另一种方法是使用proxy via reflection:
例如,如果您的User类实现了一个称为IUser(或其他任何东西)的接口,该接口声明了
String getName()
方法>public interface IUser {
String getName();
}
然后,可以使用动态代理创建一个实现InvocationHandler的IUser代理,该代理将拦截getName方法并更改其返回值。
public class DebugProxy implements java.lang.reflect.InvocationHandler {
private Object obj;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new DebugProxy(obj));
}
private DebugProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
result = m.invoke(obj, args);
if ("getName".equals(m.getName())) {
return result + "test";
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
然后,您可以申请:
public class MainApp {
public static void main(String[] args) {
IUser userProxy = (IUser) DebugProxy.newInstance(new User("foo"));
System.out.println(userProxy.getName());
}
}
System.out.println将打印“最底”
这是一个丑陋的解决方案,仅在您的User类实现公开getName方法的接口时才有效。唯一的好处是您不需要继承也不需要更改User类代码:
我会说继承是要走的路。
希望这可以帮助并欢迎堆栈溢出!