从Java中的匿名对象访问非静态对象
我使用 Google Web Toolkit 编写了一个基于模型-视图-控制器概念的应用程序。现在我的 ClientController
类有两个类型为 ClientModel
和 ClientView
的对象,它们被声明为私有且非静态的。对于异步调用的对象,我编写了一些确实有效的远程过程调用,但是从 AsyncCallback
类型附加匿名对象给我带来了问题,因为我无法访问这两个 ClientModel
和 ClientView
对象,而无需在我的函数中编写一些讨厌的 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
被高亮显示两次。谁能解释一下是否有更好的解决方案而不将 theModel
和 theView
移动到静态成员?在您访问任一组件的每个函数中编写这样的“最终包装器”是很烦人的......
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您创建非静态内部类的实例或匿名类的实例时,该实例会隐式绑定到创建的外部类的实例它。您可以使用
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
尝试声明您的成员为最终成员,如下所示:
Try and declare your members final, like this: