如何将@UiField字段设为私有

时间:2015-04-10 16:36:20

标签: java gwt sonarqube visibility

声纳抱怨以下一行:

@UiField
Button saveBtn;
  

变量' saveBtn'必须是私人的,并有访问方法。

当我将可见性修饰符设置为private时,IntelliJ IDEA会抱怨:

  

@UiField' saveBtn'不应该是'私人'

关于此冲突的最佳解决方案是什么(除了禁用此声纳警告之外)?

3 个答案:

答案 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)

你不能将这些字段设为私有字体,在这种情况下你最好修改声纳规则......