从Java中的匿名对象访问非静态对象

发布于 2024-12-02 18:59:24 字数 3938 浏览 0 评论 0原文

我使用 Google Web Toolkit 编写了一个基于模型-视图-控制器概念的应用程序。现在我的 ClientController 类有两个类型为 ClientModelClientView 的对象,它们被声明为私有且非静态的。对于异步调用的对象,我编写了一些确实有效的远程过程调用,但是从 AsyncCallback 类型附加匿名对象给我带来了问题,因为我无法访问这两个 ClientModelClientView 对象,而无需在我的函数中编写一些讨厌的 final 变量,如下所示:

package com.foo.bar;

/**
 * Represents the main handler holding delegates and controlling the contents of
 * the {@link ClientModel} and pushes notifications and message to both the
 * {@link ClientModel} and the {@link ClientView}.
 */
public class ClientController {
    /**
     * Exposes asynchronous functions to call the server component via RPC.
     */
    public static final MyServiceAsync mySvc = GWT.create(myService.class);

    /**
     * Represents the model associated with the {@link ClientController} object.
     */
    private ClientModel theModel = null;
    /**
     * Represents the view associated with the {@link ClientController} object.
     */
    private ClientView theView = null;

    /**
     * Creates a new {@link ClientController} object and instantiates both the
     * {@link ClientModel} and the {@link ClientView}.
     */
    public ClientController() {
        this.theModel = new ClientModel();
        this.theView = new ClientView(this.theModel);
    }

    /* some more code */

    /**
     * Tries to login the specified user and updates the {@link ClientView}
     * object to either an error message or the main interface.
     * 
     * @param user
     *            {@link User} object representing the user to login
     */
    public void loginUser(final User user) {
        ///////////////////////////////////////////////
        // THIS IS UGLY AND I DON'T KNOW HOW TO FIX THIS
        ///////////////////////////////////////////////
        final ClientModel currentModel = this.theModel;

        // Execute the login protocol
        ClientController.mySvc.login(user, new AsyncCallback<Boolean>() {
            /**
             * The request was successfully executed. Returns a boolean value
             * indicating whether the user was logged in.
             * 
             * @param result
             *            true, if the user was logged in; otherwise, false.
             */
            @Override
            public void onSuccess(Boolean result) {
                // The user was successfully logged in and we must both store
                // him in the model and then update the view.
                if (result) {
                    // TODO: Update the view to show the chat itself and save
                    // the current User to the ClientModel.
                    System.out.println("The User " + user.getUsername()
                            + " is now logged in!");
                    // Anonymous object can not access the theModel and theView
                    // objects of ClientController directly ...
                    // drunk, fix later!
                    // UGLY FIX FOR NOW
                    currentModel.setCurrentUser(user);
                } else {
                    // TODO: Unhide the error label of the login form and output
                    // some nice error message.
                    System.out.println("Login failed for User "
                            + user.getUsername() + "!");
                }
            }

            /**
             * The request provoked an error.
             */
            @Override
            public void onFailure(Throwable up) {
                try {
                    throw up; // Ha ha
                } catch (Throwable e) {
                    // Who cares?
                }
            }
        });
    }
}

现在我使用指向内部模型的最终指针在loginUser 被高亮显示两次。谁能解释一下是否有更好的解决方案而不将 theModeltheView 移动到静态成员?在您访问任一组件的每个函数中编写这样的“最终包装器”是很烦人的......

Working with the Google Web Toolkit i have written an application which is based on the Model-View-Controller concept. Now my ClientController class has two objects of the types ClientModel and ClientView which are declared private and non-static. With an object for asynchronous calls i have written some Remote Procedure Calls which do work, however attaching an anonymous object from the type AsyncCallback<T> makes me a problem, as i can not access the two ClientModel and ClientView objects without writing some nasty final variables in my function like you can see below:

package com.foo.bar;

/**
 * Represents the main handler holding delegates and controlling the contents of
 * the {@link ClientModel} and pushes notifications and message to both the
 * {@link ClientModel} and the {@link ClientView}.
 */
public class ClientController {
    /**
     * Exposes asynchronous functions to call the server component via RPC.
     */
    public static final MyServiceAsync mySvc = GWT.create(myService.class);

    /**
     * Represents the model associated with the {@link ClientController} object.
     */
    private ClientModel theModel = null;
    /**
     * Represents the view associated with the {@link ClientController} object.
     */
    private ClientView theView = null;

    /**
     * Creates a new {@link ClientController} object and instantiates both the
     * {@link ClientModel} and the {@link ClientView}.
     */
    public ClientController() {
        this.theModel = new ClientModel();
        this.theView = new ClientView(this.theModel);
    }

    /* some more code */

    /**
     * Tries to login the specified user and updates the {@link ClientView}
     * object to either an error message or the main interface.
     * 
     * @param user
     *            {@link User} object representing the user to login
     */
    public void loginUser(final User user) {
        ///////////////////////////////////////////////
        // THIS IS UGLY AND I DON'T KNOW HOW TO FIX THIS
        ///////////////////////////////////////////////
        final ClientModel currentModel = this.theModel;

        // Execute the login protocol
        ClientController.mySvc.login(user, new AsyncCallback<Boolean>() {
            /**
             * The request was successfully executed. Returns a boolean value
             * indicating whether the user was logged in.
             * 
             * @param result
             *            true, if the user was logged in; otherwise, false.
             */
            @Override
            public void onSuccess(Boolean result) {
                // The user was successfully logged in and we must both store
                // him in the model and then update the view.
                if (result) {
                    // TODO: Update the view to show the chat itself and save
                    // the current User to the ClientModel.
                    System.out.println("The User " + user.getUsername()
                            + " is now logged in!");
                    // Anonymous object can not access the theModel and theView
                    // objects of ClientController directly ...
                    // drunk, fix later!
                    // UGLY FIX FOR NOW
                    currentModel.setCurrentUser(user);
                } else {
                    // TODO: Unhide the error label of the login form and output
                    // some nice error message.
                    System.out.println("Login failed for User "
                            + user.getUsername() + "!");
                }
            }

            /**
             * The request provoked an error.
             */
            @Override
            public void onFailure(Throwable up) {
                try {
                    throw up; // Ha ha
                } catch (Throwable e) {
                    // Who cares?
                }
            }
        });
    }
}

For now I am using a final pointer to the internal model in loginUser which is hoghlighted two times. Can anyone explain me whether there is a better solution without moving theModel and theView to static members? It is annoying to write such "final wrappers" in every function you access either of the components...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美人骨 2024-12-09 18:59:24

当您创建非静态内部类的实例或匿名类的实例时,该实例会隐式绑定到创建的外部类的实例它。您可以使用 OuterClassName.this.member 从内部类中访问外部类的成员。

在您的情况下:ClientController.this.theModel

When you create an instance of a non-static inner class, or an instance of an anonymous class, that instance has an implicit binding to the instance of the outer class that created it. You can access members of the outer class from within the inner class using OuterClassName.this.member.

In your case: ClientController.this.theModel

浅沫记忆 2024-12-09 18:59:24

尝试声明您的成员为最终成员,如下所示:

...

private final ClientModel theModel;

private final ClientView theView;

public ClientController() {
    this.theModel = new ClientModel();
    this.theView = new ClientView(this.theModel);
}

Try and declare your members final, like this:

...

private final ClientModel theModel;

private final ClientView theView;

public ClientController() {
    this.theModel = new ClientModel();
    this.theView = new ClientView(this.theModel);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文