Java 7 での型推論の改善
(2009/9/2追記)(※注1)ダイアモンドとは、リンク先を読むと、ジェネリック型のnewで、変数の宣言にジェネリクス指定しておけば、右辺は<>(ダイヤ型)で済むということのようです。例:Map<String, List<String>> anagrams = new HashMap<>()
ほー.
以下のような感じで左辺から右辺の型引数を推測してくれるようですね.
Map<String, List<String>> map = new HashMap<>(); // saves typing
そういえば C# でも (微妙に) 似たような提案をしている人がいるという話を以前書きました.
お.これは懐かしい話題.
前から書いているが
Dictionary<List<Abrakadabra>, IEnumerable<Abrakadabra>> dic = new Dictionary<List<Abrakadabra>, IEnumerable<Abrakadabra>>();
は
Dictionary<List<Abrakadabra>, IEnumerable<Abrakadabra>> dic = new();
で書きたいんだよな。って、C#3.0ではvarキーワードと型推論が使えるから短く書けるのかな? (まだあまり使ってないのがばればれ)
仰るとおり,短さで言えば以下のように書けますね.
var dic = new Dictionary<List<Abrakadabra>, IEnumerable<Abrakadabra>>();
さて,話を戻して「左辺に合うように右辺の new を推論して欲しい」ですが,確かに同様の要望は以前からちらほら見かけました.
- Re: インスタンスに対する変数型は、本当に、一意に決まるのか? - @IT Insider.NET 会議室
- 記述の簡素化に対する要望。 - Visual Studio フィードバック
- フィードバック: 同じ型のインスタンスを宣言と同時に生成する時、型を省略したい
ただこれ,単なるマクロ (シンタックスシュガー) と見る人と,新しい推論ルール (逆順の推論; ターゲットタイプを固定して,ソースタイプをそれに近づけるもの; いわゆる暗黙の型変換的な推論) の追加と見る人でだいぶ印象が違う気がします.私は後者なので,この推論ルールを認めるなら,以下のような記法も可能ということになりますけど本当にいいんですか? とつい考えちゃうと.
static StringBuilder ReadAll(FileStream fs, StringBuilder sb) { ... } // メソッドシグネチャから引数の型は定まるので,型名を省略可能 ??? StringBuilder result = ReadAll(new ("foo.txt", FileMode.OpenOrCreate), new ());
C# で似たような型推論を提案している人たちは,メソッドシグネチャから推論ではどうして欲しかったのかちょっと気になって上の記事を書いたわけですが,Java 7 ではこのあたりどうしたいのか,元の提案を読んでみました.
関連する記述は以下となります.
The <> construct is legal to use when constructing an object and either assigning it to a variable, or when passing it as a parameter.
パラメータとして渡す場合も認めるという提案のようなので,例えば以下のようなメソッド foo があったとき,
private void foo(List<String> list) { ........ }
以下のような省略も考慮しており,これは可能としたい,という提案と読みました.
foo(new ArrayList<>()); // メソッドシグネチャから推論
まあ一貫性があるという点では好ましいと思います.が,シンタックスの話はいつも荒れるので今回はどうなんでしょうねぇ?
私の現在のスタンスは,一意に決まって首尾一貫していればまあいいんじゃねという感じですが.