Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从课外替换getter_Java - Fatal编程技术网

Java 从课外替换getter

Java 从课外替换getter,java,Java,那么,假设我有一个名为Users的类,它有一个名为name的私有变量和一个只返回name变量的公共getter方法,我如何使getter在不访问Users类的情况下为类的所有实例返回name+“test”?在Java中有几种方法可以做到这一点 子类 首先,可以扩展Users类并重写getter方法,如下所示: public class TestUser extends User { @Override public String getName() { return super.getN

那么,假设我有一个名为Users的类,它有一个名为name的私有变量和一个只返回name变量的公共getter方法,我如何使getter在不访问Users类的情况下为类的所有实例返回name+“test”?

在Java中有几种方法可以做到这一点

子类 首先,可以扩展Users类并重写getter方法,如下所示:

public class TestUser extends User {
  @Override
  public String getName() { return super.getName() + "test"; }
}
然后,您可以通过User类引用TestUser实例,并调用getName方法来使用新行为:

User tu=newtestuser(“用户名”);
tu.getName();//应返回“usernametest”

动态代理 现在。。。如果由于某种原因无法扩展您的类并且无法接触现有的用户类,那么另一种方法是使用:

例如,如果您的用户类实现了一个名为IUser的接口(或其他任何接口),该接口声明了一个
String getName()
method>

public interface IUser {
    String getName();
}
然后,使用动态代理可以创建一个IUser代理,该代理实现InvocationHandler,它将拦截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将打印“footest”

这是一个丑陋的解决方案,只有当您的用户类实现了一个公开getName方法的接口时,它才会起作用。唯一的好处是您不需要继承,也不需要更改用户类代码:

我认为继承是一条路要走


希望这有帮助,欢迎来到stack overflow

在Java中有几种方法可以做到这一点

子类 首先,可以扩展Users类并重写getter方法,如下所示:

public class TestUser extends User {
  @Override
  public String getName() { return super.getName() + "test"; }
}
然后,您可以通过User类引用TestUser实例,并调用getName方法来使用新行为:

User tu=newtestuser(“用户名”);
tu.getName();//应返回“usernametest”

动态代理 现在。。。如果由于某种原因无法扩展您的类并且无法接触现有的用户类,那么另一种方法是使用:

例如,如果您的用户类实现了一个名为IUser的接口(或其他任何接口),该接口声明了一个
String getName()
method>

public interface IUser {
    String getName();
}
然后,使用动态代理可以创建一个IUser代理,该代理实现InvocationHandler,它将拦截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将打印“footest”

这是一个丑陋的解决方案,只有当您的用户类实现了一个公开getName方法的接口时,它才会起作用。唯一的好处是您不需要继承,也不需要更改用户类代码:

我认为继承是一条路要走


希望这有帮助,欢迎来到stack overflow

将getter更改为
返回this.name+“test”?忘记添加“未访问用户类”sorry@Super您始终可以访问该类,唯一的区别是更改代码有多困难(即,任何解决方案都可以归结为更改代码),也就是说,如果需要,您可以在运行时更改字节码。将getter更改为
返回this.name+“test”?忘记添加“未访问用户类”sorry@Super您始终可以访问该类,唯一的区别是更改代码有多困难(即,任何解决方案都可以归结为更改代码),也就是说,如果需要,您可以在运行时更改字节码。天哪,您编辑了该类以包括如何使用动态代理,非常感谢!!OMG你编辑了它,包括如何使用动态代理,非常感谢!!