为什么要在Java的接口X内声明一个类型为X的变量?

huangapple go评论75阅读模式
英文:

Why would you declare a variable of type X within the interface X in Java?

问题

我最近遇到了以下的代码:

public interface Filter {
      Filter NULL_FILTER = new Filter() {
            @Override
            public Query getFilterCriteria() {
              return null;
            }
       ...
            @Override
            public void setArrayClause(ArrayClause arrayClause) {}
          };
      /** @return Filter criteria or null if not set */
      Query getFilterCriteria();
       ...
  default Filter withProjection(Set<Field> projection) {
    this.setFields(projection);
    return this;
  }
}

我对这的用途感到困惑。
有人能解释一下为什么会有人编写这段代码吗?

英文:

I ran into the following code recently:

public interface Filter {
      Filter NULL_FILTER = new Filter() {
            @Override
            public Query getFilterCriteria() {
              return null;
            }
       ...
            @Override
            public void setArrayClause(ArrayClause arrayClause) {}
          };
      /** @return Filter criteria or null if not set */
      Query getFilterCriteria();
       ...
  default Filter withProjection(Set&lt;Field&gt; projection) {
    this.setFields(projection);
    return this;
  }
}

It is confusing to me what the purpose of this could be.
Can someone explain why someone would write this code?

答案1

得分: 2

每个interface中的字段都是隐式的static,所以这并不是在定义存在于每个Filter中的内容 —— 它在Filter接口的命名空间中定义了一个通用的Filter,所以你可以简单地写成:

Filter defaultFilter = Filter.NULL_FILTER;

没有比这更复杂的。在接口中定义工厂方法或常量值并不罕见 —— 例如Java 8中的Comparator.naturalOrder()

英文:

Every field in an interface is implicitly static, so this isn't defining something that lives in every Filter -- it's defining one common Filter that is stored in the Filter interface's namespace, so you can just write

Filter defaultFilter = Filter.NULL_FILTER;

Nothing more complicated than that. It's not uncommon to have factory methods or constant values of an interface defined in that interface -- e.g. Comparator.naturalOrder() in Java 8.

答案2

得分: 1

之前的回答已经提到了NULL_FILTER是静态的,而且还是final的。这意味着NULL_FILTER是一个方便的常量,您可以在任何地方使用它。在执行此类操作时,作者应确保它确实表现为常量,方法是使对象不可变。从您分享的代码片段中看起来,它是不可变的,因为既没有getFilterCriteria也没有setArrayClause改变它的状态。不过,如果setArrayClause抛出类似于UnsupportedOperationException的异常会更好。

英文:

Previous answers have already mentioned that NULL_FILTER is static, but it is also final. Meaning NULL_FILTER is a handy constant you can use anywhere. While doing such a thing the author should ensure that it indeed behaves as a constant by making the object immutable. From the code snippet you have shared it does look immutable as neither getFilterCriteria nor setArrayClause mutates it's state. Although it would have been better if setArrayClause had thrown something like UnsupportedOperationException.

huangapple
  • 本文由 发表于 2020年9月9日 07:30:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63802823.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定