翻訳者から :この記事の著者は、
Joda Timeライブラリーと
Java Time APIの著者である
Stephen Colebourneです。
Javaで
ローカル変数型の推論を追加する必要がありますか? ちょうど今、Java開発チームがこの質問をしました。
ローカル変数のタイプの推論
JEP-286は、新しい擬似キーワード(「予約された型名」と解釈される)を使用してローカル変数の型推論を追加することを提案しています。
多くの場合、ローカル変数のタイプを明示的に示す必要はありません。 開発者が省略できるように、静的型付けを犠牲にすることなく、必要な手続きの数を減らすことにより、Javaでの開発を簡素化します。
いくつかのキーワードの提案が利用可能です:
- var-可変ローカル変数用
val
不変(最終)ローカル変数用- let-不変(最終)ローカル変数
auto
このオプションを考慮しないようにしましょう。
現在の実装戦略では、これらのオプションの前で
final
キーワードが引き続き有効であり、その結果、これらの方法のいずれかで不変変数を宣言できることが示唆されています。
final var
var-可変ローカル変数を不変に変換しますfinal val
ここでfinal修飾子は冗長であり、何も変更しませんfinal let
ここで、最終修飾子は冗長であり、何も変更しません
したがって、実際には、選択は次の組み合わせのいずれかになります。
var
およびfinal var
var
およびval
が、 final var
およびfinal val
有効var
とlet
が、 final var
とfinal let
有効です
一般に、この機能は私を喜ばせず、Javaがさらに良くなるかどうかはわかりません。 もちろん、IDEで作業する場合、型情報の欠如はスムーズになります。 ただし、通常IDEの助けを借りずに行われるため、多くの場合、これによりコードのレビューが難しくなると思います。
C#プログラミング契約では、この機能の過度の使用を推奨していないことにも注意してください。
代入の右側の式のタイプが明らかでない場合は、 var
使用しないでください。
タイプを決定するために変数の名前に依存しないでください。 それは真実ではないかもしれません。
上記にもかかわらず、私はこの改善の実装を停止する可能性がほとんどないと思います。 したがって、この記事の残りの部分では、提案されたオプションから適切なオプションを選択する方法について説明します。
Javaに最適
この改善が発表されたとき、SkalaとKotlinの支持者は
var
と
val
を使用することを自然にアドバイスし始めました。 ただし、前任者の経験から学ぶことは常に有用ですが、これはそのようなオプションがJavaにとって理想的であることを意味しません。
Javaの最適なオプションが異なる主な理由は、ストーリーです。 ScalaとKotlinでは、この機会は最初からのものでしたが、Javaではそうではありませんでした。 そして、歴史的な理由により、
val
または
let
使用がJavaに適さない理由を示したいと思います。
次のコードを検討してください。
public double parSpread(SwapLeg leg) { Currency ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); double pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; }
ここでは、ローカル変数タイプを派生させることで問題なく動作します。 しかし、コードの読み取り時にいずれかの行の変数の型が不明確であり、C#の推奨事項に従って明示的に指定することにしたと仮定します。
public double parSpread(SwapLeg leg) { val ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); val pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; }
すべて順調です。 しかし、もしこのコードがコマンドによって書かれていて、規則がローカル変数を
final
という単語で明示的にマークすることを意味する場合はどうでしょうか?
public double parSpread(final SwapLeg leg) { val ccyLeg = leg.getCurrency(); final Money convertedPv = presentValue(swap, ccyLeg); val pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; }
突然混乱がありました。 一部の場所では、単語
final
不変変数を示すために使用され、他の場所では単語
val
ます。 すべてを台無しにするのはこの混合物であり、同時に、この問題はロックとコトリンにはありません。
(おそらく、各ローカル変数に
final
を使用しないのでしょうか?私は使用しません。しかし、これは非常に合理的な標準であり、開発セキュリティを改善し、エラーを減らすために考案されたものです。)
そして、これが代替案です。
public double parSpread(final SwapLeg leg) { final var ccyLeg = leg.getCurrency(); final Money convertedPv = presentValue(swap, ccyLeg); final var pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; }
Javaの場合、これははるかに一貫しています。
final
という単語は、不変の変数を指定するためのユビキタスなメカニズムであり続けています。 そして、私のように、どこでも
final
に署名する必要があると思わない場合は、単にそれを削除します:
public double parSpread(final SwapLeg leg) { var ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); var pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; }
私は多くの読者がこの場所で持っている異議を理解しています。 同様に、2つの新しい「キーワード」があり、1つは可変ローカル変数、もう1つは不変ローカル変数であり、不変バージョンをより頻繁に使用するように両方を同じ長さ(または可変の単語でも長くする)にする必要があります。
しかし、Javaではそれほど単純ではありません。 「
final
」という言葉は長年にわたって存在し
final
います。 この事実に目を向けると、コードはくて一貫性のない混乱に変わります。
おわりに
個人的には、ローカル変数のタイプの結論がまったく好きではありません。 しかし、まだそれを行うことに決めた場合、既存の言語にうまく適合することが必要です。
私の立場は、
val
と
let
Javaには適さないということです。なぜなら、
final
という単語がすでに存在し、明確な意味を持っているからです。
var
と
final var
持つバリアントは完全で
final var
ませんが、これが既存の言語に適合する唯一の組み合わせであると思います。