Androidのチュートリアル(マルチスレッド、ルーパー、ハンドラーに関連する)を見て、私はこれに出くわしました:
public synchronized void enqueueDownload(final DownloadTask task)
私の質問は次のとおりです。
- 関数のパラメーターをfinalとして宣言する必要があるのはいつ、そしてなぜですか?
- それはJavaに固有のものですか、それともC / C ++などの他の言語にも同様のものが存在しますか?
Androidのチュートリアル(マルチスレッド、ルーパー、ハンドラーに関連する)を見て、私はこれに出くわしました:
public synchronized void enqueueDownload(final DownloadTask task)
私の質問は次のとおりです。
Java では、これは通常、匿名の内部クラス内のパラメーターにアクセスできるようにするためです。これは、Android でイベント ハンドラーなどによく使用されます。
本当の意味は、パラメーターの値をメソッド内で変更できないことですが、目的は通常、匿名の内部クラスのためです...
public synchronized void enqueueDownload(final DownloadTask task) {
SomethingHandler handler = new SomethingHandler() {
@Override public void handleSomething() {
// This would not compile if task were not final
task.doSomething();
}
};
// Use handler
}
あなたの文脈では、そのパラメータの最後のキーワードは、変数タスクをメソッド本体内で再割り当てできないことを意味し、セキュリティ上の理由から指定されています。
同様の動作は、定数関数パラメーターを使用してC++で実現できます。
関数を作成していて、パラメーターを変更する予定がない場合は、それが定数参照パラメーターであることを宣言できます。
再割り当てしてはならないことがわかっている場合は、最終的なものとして宣言します。メソッドパラメータを再割り当てすることはめったに意味がないため、メソッドパラメータに対してこれを実行することがよくあります。
void foo(String str) { // no final
str = "hijacked"; // perfectly fine
}
void foo(final String str) { // final
str = "hijacked"; // compile error
}
CとC++はのconst
代わりに使用しますfinal
が、詳細をすぐに知っているとは言えません。
final キーワードは、修飾子としていくつかの異なるコンテキストで使用されます。これは、それが変更するものを何らかの意味で変更できないことを意味します。
最終クラス
Java ライブラリの多くのクラスが final と宣言されていることに気付くでしょう。
public final class String これは、このクラスがサブクラス化されないことを意味し、他の方法では実行できない特定の最適化を実行できることをコンパイラに通知します。また、セキュリティとスレッド セーフに関しても利点があります。
コンパイラでは、final と宣言されたクラスをサブクラス化することはできません。ただし、独自のクラスを final として宣言したくない、または宣言する必要はないでしょう。
最終的な方法
メソッドが final であることを宣言することもできます。final と宣言されたメソッドは、サブクラスでオーバーライドできません。構文は単純です。次のように、キーワード final をアクセス指定子の後、戻り値の型の前に置くだけです。
public final String convertCurrency()
最終フィールド
フィールドを final として宣言することもできます。これは、メソッドまたはクラスを final として宣言することと同じではありません。フィールドが final と宣言されている場合、それは変更されず、変更できない定数です。1 回設定できます (たとえば、オブジェクトの構築時ですが、その後変更することはできません)。変更しようとすると、コンパイル時エラーまたは例外が生成されます (その試みがどれほど巧妙であるかによって異なります)。
final、static、public の両方であるフィールドは、実質的に名前付き定数です。たとえば、物理プログラムは Physics.c を定義し、光の速度を次のように定義します。
public class Physics {
public static final double c = 2.998E8;
}
SlowCar クラスでは、speedLimit フィールドは非公開ですが、最終的かつ静的である可能性があります。
public class SlowCar extends Car {
private final static double speedLimit = 112.65408; // kph == 70 mph
public SlowCar(String licensePlate, double speed, double maxSpeed,
String make, String model, int year, int numberOfPassengers, int numDoors) {
super(licensePlate,
(speed < speedLimit) ? speed : speedLimit,
maxSpeed, make, model, year, numberOfPassengers, numDoors);
}
public void accelerate(double deltaV) {
double speed = this.speed + deltaV;
if (speed > this.maxSpeed) {
speed = this.maxSpeed;
}
if (speed > speedLimit) {
speed = speedLimit;
}
if (speed < 0.0) {
speed = 0.0;
}
this.speed = speed;
}
}
最終引数
最後に、メソッドの引数が final であることを宣言できます。これは、メソッドがそれらを直接変更しないことを意味します。すべての引数は値で渡されるため、これは絶対に必要というわけではありませんが、役立つ場合があります。