Javaで自動型推論はありますか?


113

autoC ++のようなJavaの変数型はありますか?

例:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Javaには強化されたforループがあることは知っていますが、自動はありますか?そうでない場合、これを行うためのハックはありますか?C ++ 11の新機能について言及しています


1
基本的な型を除くすべてを型の変数に割り当てることができるObjectため、一部の操作では、必要なObject場所で使用できますauto
Zyx 2000

1
javaにはそのような変数はありません
Aleksei Bulgak

@ Zyx2000:次に、to_string問題の実際のオブジェクトではなく、オブジェクトの関数を使用しますか?
Games Brainiac 2013

2
@GamesBrainiac:いいえ、上書きされたバージョンがあればそれを使用します。
Keppil

2
あなたが探している用語は「自動」ではなく、「型推論」です。Javaでは型推論についてかなりの数の質問がありますが、それらはほとんどジェネリックを参照しているため、重複を見つける方法がわかりません...

回答:


49

質問が編集される前に回答:

いいえauto、Java には変数型はありません。同じループを次のように実現できます。

for ( Object var : object_array)
  System.out.println(var);

Javaにはローカル変数があり、そのスコープはそれらが定義されているブロック内にあります。CおよびC ++に似ていますが、autoまたはregisterキーワードはありません。ただし、Javaコンパイラーは、明示的に初期化されていないローカル変数の使用を許可せず、コンパイルエラーを出します(コンパイラーが通常警告のみを与えるCおよびC ++とは異なります)。礼儀:ウィキペディア

いいえ、JavaにはC ++のような主流の型推論はありません。RFEがありましたが、これは「修正されません」としてクローズされました。理由は次のとおりです。

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


10
@GamesBrainiacいいえ、メソッド呼び出しは常にJavaではポリモーフィックです。ただし、他の多くのこと(たとえば、オーバーロードの解決、またはで定義されていない操作Object)は、このように行うことはできません。これは実際には良い答えではありません。問題の例が弱いためにうまくいくだけです。

10
この質問はC ++ 11での型推論に関するものでありauto、CやC ++ 11より前のバージョンでの以前の使用に関するものではありません。あなたの編集はトピックから外れています。

4
「それは私が意図したものではありません。オブジェクトに型キャストすると、オブジェクトのto_stringが得られます」偽。絶対に100%偽。
Louis Wasserman 2013

140
「人間は冗長性の恩恵を受けています。」それは本当です。毎朝目を覚まし、「どうすればコードをより冗長にすることができますか」と思います。メリットがあるからです。
ahoffer 2015

2
また、この答えは廃止理由があるvarのJava 9.以来、予約済みのキーワードである
6infinity8

69

たぶん、Java 10にはvarキーワードを通じてあなた(そして私)が望んでいるものがあります。

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

JDK強化の提案286


更新:はい、その機能によりJava 10リリースに組み込まれました!


6
Yaは改善されましたが、そのキーワードはローカル変数でのみ機能します。C ++自動型推論ほど強力ではない
texasbruce

7
マイナーなnit-pick:varはキーワードではありません!JLSから:「varはキーワードではなく、ローカル変数宣言のタイプとして特別な意味を持つ識別子です」。したがって、キーワードとは異なり、変数またはメソッド「var」の呼び出しを止めるものは何もありません。
クリトスキリアク

2
良い点@KlitosKyriacou。それでも、「keyword」を「identifier」に、または「identifierをローカル変数宣言のタイプとして特別な意味を持つ」に置き換えることを想像すると、答えは不明確になると思います。しかし、そうです、var確かにキーワードのリストにはありません。
sorrymissjackson

これは、下位互換性のためだけのキーワードではありません。この名前の識別子を持つことができるという事実に加えて、varはキーワードの役割を果たします。
facetus

25

Java 7はdiamond構文を導入します

Box<Integer> integerBox = new Box<>(); // Java 7

古いjavaと比較して

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

批判的な読者は、この新しい構文は、元の質問でforループを記述するのに役立たないことに気付くでしょう。それは正しく、完全に意図的なようです。Oracleのバグデータベースを引用している他の回答を参照してください。


4
真が、何彼(と私は)を探していることのようなものは次のとおりですauto integerBox = new Box<Integer>();、これは通常、時々のように複合体を形成することができる機能からの戻り値を取得するために使用されるHashMap<String, LinkedList<Operation, Set<Integer>>>
Roee Gavirel

1
その懸念は、コードサンプルの後で私が正確に対処したものです。結論は、Javaはそれを行わないということであり、それは意図的なものです。
Tarrasch 2014年

18

Java 8では、ラムダ型推論を使用して、型の宣言を回避できます。質問者の例に類似するものは次のとおりです。

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

どちらもメソッド参照を使用して簡略化できます。

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

8

つまり、自動タイプはありません。ただし、値を出力するだけの場合は、値をとして参照できますObject


またはhashCodesを計算するか、クラス名を収集するか、または...あなたはアイデアを思いつきました;)しかし、リストは短いです。オブジェクトクラスのドキュメントを参照してください(コメントは初心者向けです。きっとSimonCをご存知でしょう)
Alexander Malakhov

4

これは純粋なJavaソリューションではありませんが、lombokと呼ばれるライブラリを追加すると、以下の魔法がコンパイルさautoれ、C ++のキーワードと非常によく似た動作をします。

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.