Java 8常量函数命名约定



我知道Oracle Java的命名约定,我读过类似的SO问题(如Java常量变量,命名约定),但我应该为常量函数使用什么命名?

。如果我有功能界面

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");

在Java中,没有"常量函数"这样的东西:lambda构造一个具有单一方法的对象,并且,像所有其他对象一样,它可以被分配给引用—包括一个final参考。在引用StringDecider STRING_NOT_EMPTY的级别上,使用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具有等效的函数—它们只是使用不同的语法来定义,可能会或可能不会以不同的方式实现。结论

在引用级别,对象是否使用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());

如果,无论出于何种原因,您和/或您的团队想要区分这两者,请随意这样做……但一定要保持一致。


事实上,lambdas和匿名类不需要以相同的方式实现。然而,一旦它们被创建,它们的用法是相同的(有一些差异,比如在变量范围内,但是,一旦对象被创建并分配给StringDecider STRING_NOT_EMPTY,这些差异就不再相关了)。

当某些内容是常量时,可以使用带下划线的大写字母来分隔单词。这对所有东西都是一样的,变量,字段,对象和常量。

from Oracle's site:

声明类常量和ANSI常量的变量名应该全部大写,单词之间用下划线(_)分隔。(为了便于调试,应该避免使用ANSI常量。)

如果您没有像使用其他静态final变量那样使用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,在其他变量中,感觉有点难看。

我觉得静态final函数应该与方法"类似",大写并相应地放置,所以对我来说更自然的是:

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。我们通常将私有方法写在使用它们的公共方法的下面。在我看来,把私有函数写在使用它们的公共方法下面也是合理的。

但请注意,我在这里的理由中有很多"感觉",这可能是也可能不是足够的理由。


我注意到,在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的编译器警告)

最新更新