声纳抱怨以下一行:
@UiField
Button saveBtn;
变量' saveBtn'必须是私人的,并有访问方法。
当我将可见性修饰符设置为private
时,IntelliJ IDEA会抱怨:
@UiField' saveBtn'不应该是'私人'
关于此冲突的最佳解决方案是什么(除了禁用此声纳警告之外)?
答案 0 :(得分:2)
GWT的代码生成要求@UiFields
不是私有的。在编译期间运行的UIBinder代码生成器将为您创建大量Java代码,并将其动态添加到项目中。
此代码将直接访问字段并将小部件绑定到您的变量。这个生成的代码没有使用任何访问器,也没有允许这样做的选项。 (实际上,这是完全合理的,因为它掩盖了事实,这些变量实际上已设置并使注释的语义清晰)。
这是要求背后的基本原理,这些字段不允许私有。因此,没有办法解决这个问题,但是要禁用该类的声纳警告。
答案 1 :(得分:1)
对于UiBinder(以及GWT的许多其他功能,如i18n,ClientBundles等),GWT编译器在与视图相同的包中生成一个额外的Java类。该类必须访问视图的字段(例如,实例化它们),因此它们需要是包可见的(也称为默认值)。 private
不符合此要求。
让我们看一个例子:
我们在某个软件包中有ApplicationView.java
:
public class ApplicationView extends Composite {
/* Needs to be package visible too */
interface Binder extends UiBinder<Widget, ApplicationView> {
}
/* Doesn't matter what modifiers are here, but
it's usually static to give a hint to the GWT compiler
that this field can be shared between instances of
this class (like a, well, static)
*/
private static Binder binder = GWT.create(Binder.class);
@UiField Button button;
public ApplicationView() {
initWidget(binder.createAndBindUi(this));
}
}
在同一个程序包中,您ApplicationView.ui.xml
定义了视图的布局方式。
您通常不会看到GWT编译器为每个UiBinder视图生成一个额外的Java类。在这种情况下,它在ApplicationView_BinderImpl.java
,在同一个包中,但在不同的源文件夹中。这取决于您用于构建项目的内容,但是如果我使用了maven项目,那么它就在target/.generated
中。
以非常简短的形式,ApplicationView_BinderImpl
可能如下所示:
public class ApplicationView_BinderImpl implements UiBinder<com.google.gwt.user.client.ui.Widget, com.example.ApplicationView>, com.example.ApplicationView.Binder {
public com.google.gwt.user.client.ui.Widget createAndBindUi(final com.example.ApplicationView owner) {
return new Widgets(owner).some_generated_method();
}
}
如您所见,此类实现您在视图中定义的Binder
接口。当您从视图中调用createAndBindUi
时,将视图实例传递给此方法 - 这样,此方法可以实例化所有@UiField
等等。如果这些字段是私有的,则此类无法访问它们。
答案 2 :(得分:0)
你不能将这些字段设为私有字体,在这种情况下你最好修改声纳规则......