将 java.util.function.Function 定义为静态最终
Defining java.util.function.Function as static final
在我的代码中,我们必须将欧元转换为欧分:将 BigDecimal
作为输入,我们必须将其乘以 100。
我们需要多次应用此转换,因此我们决定使用来自 java.util.function
的 UnaryOperator
:
private static final UnaryOperator<BigDecimal> CONVERT_EURO_TO_CENTS =
input -> input.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.DOWN);
然后我们使用CONVERT_EURO_TO_CENTS
如下:
[.....]
CONVERT_EURO_TO_CENT.apply(<aBigDecimal>)
[.....]
将 UnaryOperator
声明为常量 (static final
) 以避免多线程环境中的数据不一致(线程安全)会很危险吗?
不,这并不危险。
如果您创建一个可变对象并将其放在静态字段中,那么不同的线程可能会更改其状态并引起麻烦。
这里虽然静态最终字段包含对 lambda 的引用,但没有任何内容是可变的。它没有任何多线程可以篡改的状态。 BigDecimal 上的每个操作都是线程安全的,BigDecimal 是不可变的。即使 BigDecimal 不是线程安全的,其他线程也无法访问传递给 lambda 的参数。
顺便说一句,如果你用局部变量实现 lambda,那仍然是线程安全的,唯一的状态被限制在执行该方法的堆栈帧中。
考虑一下如果你打算把这个 lambda 放在一个变量中并在不同的地方使用它,你还不如使用静态方法。你没有得到任何使它成为 lambda 的东西。如果您需要将其作为参数传递,您仍然可以使用方法引用来实现。
在我的代码中,我们必须将欧元转换为欧分:将 BigDecimal
作为输入,我们必须将其乘以 100。
我们需要多次应用此转换,因此我们决定使用来自 java.util.function
的 UnaryOperator
:
private static final UnaryOperator<BigDecimal> CONVERT_EURO_TO_CENTS =
input -> input.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.DOWN);
然后我们使用CONVERT_EURO_TO_CENTS
如下:
[.....]
CONVERT_EURO_TO_CENT.apply(<aBigDecimal>)
[.....]
将 UnaryOperator
声明为常量 (static final
) 以避免多线程环境中的数据不一致(线程安全)会很危险吗?
不,这并不危险。
如果您创建一个可变对象并将其放在静态字段中,那么不同的线程可能会更改其状态并引起麻烦。
这里虽然静态最终字段包含对 lambda 的引用,但没有任何内容是可变的。它没有任何多线程可以篡改的状态。 BigDecimal 上的每个操作都是线程安全的,BigDecimal 是不可变的。即使 BigDecimal 不是线程安全的,其他线程也无法访问传递给 lambda 的参数。
顺便说一句,如果你用局部变量实现 lambda,那仍然是线程安全的,唯一的状态被限制在执行该方法的堆栈帧中。
考虑一下如果你打算把这个 lambda 放在一个变量中并在不同的地方使用它,你还不如使用静态方法。你没有得到任何使它成为 lambda 的东西。如果您需要将其作为参数传递,您仍然可以使用方法引用来实现。