web-dev-qa-db-ja.com

Java型推論を行わないのはなぜですか?

なぜJavaが言語であるとしても型推論を行わないのか、そのVMは非常に成熟しているため、GoogleのGoがその例です優れた型推論を備えた言語のおかげで、実行する必要がある入力の量が減少します。この機能がJavaの一部ではないことの背後に特別な理由はありますか?

45
cobie

技術的に言えば、ジェネリックを使用する場合、Javaには型推論があります。 ジェネリックメソッド お気に入り

_public <T> T foo(T t) {
  return t;
}
_

コンパイラは、あなたが書くときにそれを分析して理解します

_// String
foo("bar");
// Integer
foo(new Integer(42));
_

引数として入力されたものに基づいて、最初の呼び出しではStringが返され、2番目の呼び出しではIntegerが返されます。結果として、適切なコンパイル時チェックが行われます。さらに、Java 7では、 インスタンス化ジェネリック のように、型推論を追加できます

_Map<String, String> foo = new HashMap<>();
_

Javaは、山かっこを空白で埋めてくれます。なぜJavaサポート型推論が変数代入の一部としてサポートされないのですか?)ある時点で、 [〜#〜] rfe [〜#〜] 変数宣言での型推論用ですが、これは「修正されません」として閉じられました。

人間は、型宣言の冗長性から2つの方法でメリットを得ます。まず、冗長な型は貴重なドキュメントとして機能します。リーダーはgetMap()の宣言を検索して、それが返す型を見つける必要はありません。第2に、冗長性により、プログラマーは目的の型を宣言できるため、コンパイラーが実行するクロスチェックのメリットを享受できます。

これをクローズした寄稿者は、私が同意する1人である「Javaに似ていない」と感じていることにも言及しました。 Javaの冗長性は祝福と呪いの両方になる可能性がありますが、それは言語をそのとおりにするものです。

もちろん、その特定のRFEはその会話の終わりではありませんでした。 Java 7の間、この機能は 再び考慮されました 。James Gosling自身によるものを含むいくつかのテスト実装が作成されました。この場合も、この機能は最終的に撃墜されました。

Java 8のリリースにより、ラムダの一部として型推論を取得できるようになりました。

_List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));
_

Javaコンパイラは、メソッド Collections#sort(List<T>, Comparator<? super T>)のインターフェイスを確認できます) Comparator#compare(T o1, T o2) およびfirstsecondStringである必要があることを判別し、プログラマーがラムダ式。

61
user7007

まず、型推論にはnothingがあり、ランタイムが30年前のCPUであろうとVMであろうと新しいビットであろうと、ランタイムの成熟度と関係があります。まだ光沢があります。それはすべてコンパイラに関するものです。

そうは言っても、ジェネリックは許可されていますが、ジェネリック以外の型が許可されていない理由は哲学によるものと思われます-デザイナーがそれを追加するのを妨げるものは何もありません。

更新:Javaのように見えます10でサポートされています- http://openjdk.Java.net/jeps/286

16
jmoreno

私の知る限り、Javaが90年代の初めに設計されたとき、型推論は主流言語の間ではそれほど一般的ではありませんでした(しかし、それはすでにMLなどの非常によく知られた概念でした)。したがって、Javaは、C++、Pascal、またはそれを持たない他の主流言語(最小の驚きの原則)から来たプログラマーを対象としたものであるため、おそらく型推論がサポートされていなかったと想像できます。

また、Javaの設計原則の1つは、プログラマーとコンパイラーがコードを同じように理解できるように明示的に記述することです:情報を複製するとエラーの可能性が減ります。もちろん、 、あと2、3文字入力することで安全性を高める価値があるかどうかは好みの問題かもしれませんが、これはJavaの設計哲学でした。

Javaが将来型推論を取得するかどうかはわかりませんが、言語にとって大きな革命となるIMOです(Glenn Nelsonが述べたように、それは「Javaに似ていない」と説明されていました) )そして、新しい名前を優先して、名前Javaを削除することを検討することもできます。

型推論でJVM言語を使用したい場合は、Scalaを使用できます。

5
Giorgio

いくつかの理由が考えられます。 1つは、明示的な型指定が自己文書化されることです。 Javaは通常、これを簡潔さよりも優先します。もう1つの理由は、型がややあいまいな場合です。型またはサブタイプがルーチンを満たす場合と同様です。たとえば、リストですが、誰かがやって来てArrayList専用のメソッドを使用しています。コンパイルエラーが発生した場合でも、JITはArrayListを推測して続行します。

2
jiggy

これは、ニーズに適合する最も一般的なインターフェイスを使用して変数を宣言し、適切な実装クラスでそれらを初期化するという、確立された推奨事項とは矛盾します。

_Collection<String> names = new ArrayList<>();
_

事実上、

_var names = new ArrayList<String>();
_

の構文糖にすぎない

_ArrayList<String> names = new ArrayList<String>();
_

あなたがそれを望むなら、あなたのIDEはnew ArrayList<String>()式から "ワンクリック"(リファクタリング/ローカル変数を作成)でそれを生成できますが、 "使用インターフェース」の推奨事項。

0
Ralf Kleberhoff