在 Java 中使用 final 方法参数
Using final in method parameters in Java
作为刚切换到 Java 的用户,我意识到在我们的项目和其他一些 Java 项目中, final
关键字是常用的,并且在阅读了几个教程和 SO线程例如Excessive use "final" keyword in Java,我认为有些示例不需要 final
关键字。所以,这里有几点我很困惑:
1. 类和接口的方法参数中是否需要使用final
关键字?因为
CompanyDTO findByUuid(final UUID uuid);
//or
@Override
public CompanyDTO findByUuid(final UUID uuid) {
//...
}
2. 据我所知,它对线程安全也有好处,但我需要了解基本原理Java 中几乎所有可能的地方都使用了它。一般用于不会改变的变量。那么,您能解释一下常用用法吗?
- Is there any need to use final keyword in method parameters in classes and interfaces?
None。因为使用效果微乎其微
- As far as I know, it also good for thread safety
完全没有。对 primitive 参数的更改在方法主体外部 not 可见。另一方面,final
不会阻止您在引用类型参数上调用 方法 。
换句话说:如果您的方法主体执行的操作最终导致不同线程之间出现竞争条件,那么 final
根本无济于事。
绝对 仅 使用 final
作为参数会阻止您做的事情:重新为其赋值。因此,它 可以 有助于防止愚蠢的错误。但这几乎归结为纯粹的风格。以我为例,我几乎从不使用它,大多数时候认为它没用clutter/noise。
- 在方法参数上使用 final 修饰符没有多大意义
因为它在没有的情况下给方法声明增加了视觉混乱
买你很多。只要你能确保你不重新分配
这些变量的值,你已经足够好了,没有 final
方法参数修饰符。
- 方法参数在栈上,而且是局部的
特定线程,只要该线程不将其发布给某些人
其他线程。因为它不在其他线程之间共享,所以不
这里出现线程安全问题。但是,如果当前线程
发表这些论点,那么你就不走运了,使用
final 修饰符不给你任何线程安全保证。
这是对 final 修饰符的一种如此有品位的用法,用于编写一个不可变的 class,它表示我们二维 space.
中的一个点
class Point2D {
private final int x;
private final int y;
Point2D(int x, int y) {
this.x = x;
this.y = y;
}
// Remainder omitted for brevity's sake !
}
创建此 class 实例后,您可以与其他线程自由共享它,而无需费心同步对其状态的访问。因此,不可变对象免费为您提供线程安全。
您可以阅读 JLS § 17.5 以获取有关最终字段语义的更多详细信息。
1. Is there any need to use final keyword in method parameters in classes and interfaces?
这取决于这些方法的作用。
例如,如果它们包含 lambda,则适用某些规则。
参见 JLS §15.27.2
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
作为刚切换到 Java 的用户,我意识到在我们的项目和其他一些 Java 项目中, final
关键字是常用的,并且在阅读了几个教程和 SO线程例如Excessive use "final" keyword in Java,我认为有些示例不需要 final
关键字。所以,这里有几点我很困惑:
1. 类和接口的方法参数中是否需要使用final
关键字?因为
CompanyDTO findByUuid(final UUID uuid);
//or
@Override
public CompanyDTO findByUuid(final UUID uuid) {
//...
}
2. 据我所知,它对线程安全也有好处,但我需要了解基本原理Java 中几乎所有可能的地方都使用了它。一般用于不会改变的变量。那么,您能解释一下常用用法吗?
- Is there any need to use final keyword in method parameters in classes and interfaces?
None。因为使用效果微乎其微
- As far as I know, it also good for thread safety
完全没有。对 primitive 参数的更改在方法主体外部 not 可见。另一方面,final
不会阻止您在引用类型参数上调用 方法 。
换句话说:如果您的方法主体执行的操作最终导致不同线程之间出现竞争条件,那么 final
根本无济于事。
绝对 仅 使用 final
作为参数会阻止您做的事情:重新为其赋值。因此,它 可以 有助于防止愚蠢的错误。但这几乎归结为纯粹的风格。以我为例,我几乎从不使用它,大多数时候认为它没用clutter/noise。
- 在方法参数上使用 final 修饰符没有多大意义 因为它在没有的情况下给方法声明增加了视觉混乱 买你很多。只要你能确保你不重新分配 这些变量的值,你已经足够好了,没有 final 方法参数修饰符。
- 方法参数在栈上,而且是局部的 特定线程,只要该线程不将其发布给某些人 其他线程。因为它不在其他线程之间共享,所以不 这里出现线程安全问题。但是,如果当前线程 发表这些论点,那么你就不走运了,使用 final 修饰符不给你任何线程安全保证。
这是对 final 修饰符的一种如此有品位的用法,用于编写一个不可变的 class,它表示我们二维 space.
中的一个点class Point2D {
private final int x;
private final int y;
Point2D(int x, int y) {
this.x = x;
this.y = y;
}
// Remainder omitted for brevity's sake !
}
创建此 class 实例后,您可以与其他线程自由共享它,而无需费心同步对其状态的访问。因此,不可变对象免费为您提供线程安全。
您可以阅读 JLS § 17.5 以获取有关最终字段语义的更多详细信息。
1. Is there any need to use final keyword in method parameters in classes and interfaces?
这取决于这些方法的作用。 例如,如果它们包含 lambda,则适用某些规则。
参见 JLS §15.27.2
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.