Java 8常量函数命名约定

时间:2016-11-07 17:10:07

标签: java java-8

我知道Oracle Java naming conventions并且我读过类似的SO问题(例如Java constant variable, naming convention)但是我应该使用什么命名来表示常量函数?

E.g。如果我有功能界面

public interface StringDecider {
  public boolean decide(String str);
}

现在我用它来定义一个常量函数。命名应该是“上蛇案”,如

public final static StringDecider STRING_NOT_EMPTY = (str) -> (str!=null && !str.isEmpty());
STRING_NOT_EMPTY.decide("Example");

或驼峰案例

public final static StringDecider stringNotEmpty = (str) -> (str!=null && !str.isEmpty());
stringNotEmpty.decide("Example");

3 个答案:

答案 0 :(得分:4)

在Java中,没有"常量函数":lambda构造an object which has a single method,和所有其他对象一样,它可以分配给引用 - 包括{ {3}}参考。在引用StringDecider STRING_NOT_EMPTY的级别上,使用lambda创建的对象与通过任何其他方式创建的对象之间没有区别。因此,术语"常数"取决于用于定义和构造常量对象的构造,具有不同的含义。

事实上,除了在代码中的定义之外,lambda函数对象与例如lambda函数对象之间没有明显的区别。匿名类对象

public final static StringDecider STRING_NOT_EMPTY_LAMBDA = str -> (str != null && !str.isEmpty());

public final static StringDecider STRING_NOT_EMPTY_ANON = new StringDecider() {

    @Override
    public boolean decide(final String str) {
        return str != null && !str.isEmpty();
    }

};

出于所有意图和目的,STRING_NOT_EMPTY_LAMBDASTRING_NOT_EMPTY_ANON具有相同的功能 - 它们只是使用不同的语法定义,final

结论

在引用级别,没有区别对象是否使用lambda定义。因此,对于使用lambda创建的常量,为了保持一致性,您可能应该使用与其他方式创建的常量相同的约定:

public final static int ANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42;

public final static StringDecider STRING_NOT_EMPTY = str -> (str != null && !str.isEmpty());

如果出于某种原因,您和/或您的团队想要辨别两者之间,请随意这样做......但请务必保持一致。

事实上,may or may not be implemented differently。但是,它们的使用在创建后是相同的(差异很小,例如在变量范围内,但是,一旦创建对象并将其分配给StringDecider STRING_NOT_EMPTY,这些差异就不再相关了。)

答案 1 :(得分:1)

当某些内容不变时,您可以使用带下划线的大写字母来分隔单词。对于所有事物,变量,字段,对象和常量lambda也是如此。

来自Oracle's site

  

声明类常量和ANSI常量的变量名称应全部为大写,并用下划线(“_”)分隔。 (为了便于调试,应避免使用ANSI常量。)

答案 2 :(得分:0)

如果您没有像任何其他静态最终变量一样使用SNAKE_CASE_CAPS,您的IDE可能会发出警告。

在这方面,我从Oracle中找不到任何建议你应该区别对待lambda与其他任何类型。

我在JDK源代码中找不到任何示例。我在Guava中发现了一些使用SNAKE_CASE_CAPS的例子。

然而团队和个人可以并且确实发明了本地约定(例如,某些项目使用snake_case_lower_case_for_test_methods_in_jUnit()),如果您认为它有用,您可以采用本地在你的情况下的惯例。

我个人觉得:

  • myStream.map(MY_FUNCTION)感觉有点难看。
  • 在文件顶部声明lambdas,在其他变量中,感觉有点难看。

我觉得静态的最终功能应该是"排序同行"方法,大写和相应的位置,所以我觉得有这样的感觉更自然:

private List<String> asStrings(List<Foo> foos) {
     return foos.stream().map(fooToString).collect(toList());
}

private static final Function<Foo,String> fooToString = f -> 
     "Foo: " + foo.id;

...而不是将文件顶部的函数声明为FOO_TO_STRING。我们通常在使用它们的公共方法下面编写私有方法。在使用它们的公共方法下编写私有函数似乎是合理的。

但请注意,有很多&#34;感觉&#34;在我的理由中,这可能是也可能是不充分的理由。

我注意到在Oracle Java源代码中,标准代码通过不使用静态变量来回避这个问题。例如,在Function.java

 static <T> Function<T, T> identity() {
      return t -> t;
 }

...返回一个内联的新Function对象,而不是重用存储在类或对象变量中的共享Function对象。

另请注意,您可以声明普通的静态方法并将它们用作函数,但使用this或类名称与::的使用会略有开销:

private static String slimify(String s) {
    return "Slim says: " + s;
}

...

out = stream.map(this::slimify).collect(Collectors.toList());

(我目前没有收到关于在静态上下文中使用this的编译器警告)