Java7 のダイアモンドオペレータと型推論について。
http://bit.ly/n09Sre ちょっとこれを読んで思った事。newするときに、 new ArrayList<? extends String>(); ができないのは、自然というか当然のように #java
2011-07-31 15:31:24思っていた。というのは、? extends Stringなんて型は、「ファーストクラスの型としては」存在しないから。というのが1点。あと、new java.util.ArrayList<? extends String>(); って一体何をnewしたいのかって話がある。
2011-07-31 15:35:05よく誤解されるところではあるんだけど(これは、@nagise さんに言っているわけではありません)、? extends Stringの、?は、ジェネリックスの実型引数における「修飾子」のようなものであって、それ自体は型を構成しない。
2011-07-31 15:37:07つまり、 ? extends String f = null; とかこんな事はできないよね、って話。(? extends T)は「型ではない」というのが重要。
2011-07-31 15:38:51、さっきのもう一つの方の話。さて、new java.util.ArrayList<? extends String>()が仮にできたとして、これは一体何を意図しているのだろうか?「Stringのサブタイプの内どの型が入っているかわからないコンテナ」ということになるだろうけど、
2011-07-31 15:43:35これが仮にできたとして、実際にはまず役に立たない。このnewしたnew java.util.ArrayList<? extends String>();に対してできる操作は、add(null); とかdeteleとかget系くらいしかないので、無理やりキャストでもしない限り
2011-07-31 15:45:25あと、"これ、どうなってるかというと、Javaのジェネリクスはイレイジャ方式なのでなんか適当にnew ArrayList()しちゃってるようです。" 実装としてはそうですが、diamond operatorの意味としては、new ArrayList<String>();を推論
2011-07-31 16:03:20してないとまずい気がする。diamond operatorの趣旨は、あくまで推論することであって、無検査キャストを通すようなものではないはずなので。この辺、正式な仕様書があればはっきりするんだけど…。
2011-07-31 16:05:54この辺の仕様(というには未定義部分が多過ぎるが) file:///C:/Users/Mizushima/Downloads/enhancements-1_0-final-eval-spec/Jsr334-v1.0-FR.html#diamond 読む限りでは、やっぱり
2011-07-31 16:10:23Stringとかその辺りの型パラメータが推論されるはず。 "In both cases, the compiler infers Object as the value of type argument for the constructor. " と書いてるわけだし。
2011-07-31 16:11:43diamond operatorの趣旨は、仕様に "the diamond syntax is used to mark locations where type inference is requested" 書かれてる。要は<>の部分の型を推論してくださいね、という。
2011-07-31 16:28:20あー、なるほど。diamond operatorは、基本的にJSR3rd の 15.12.2.7と15.12.2.8における型パラメータ推論規則を使うためのシンタックスシュガーのようなものとと考えて、おおむね間違い無さそう。
2011-07-31 16:33:26http://bit.ly/qtMAD6 …Javaレベルでのループはバイトコードではジャンプ命令に変換されるわけでありまして…。バイトコードでジャンプ命令使ったって、VM側からループと認識されたらそれで終わりのような…。というか、単にわかっててネタで言ってるだけだよね。
2011-07-31 17:06:46@kmizu んー。raw型がすべてを受け入れるのに対し、推論が必要なところをマークするという話ですよね。そこから「推論しろ」というのはちょっと飛躍に思えるなあ
2011-07-31 23:54:04@nagise "In both cases, the compiler infers Object as the value of type argument for the constructor." と書いてあるわけです。
2011-08-01 00:28:59@kmizu たしかに書いてはありますね。んー。ただこの例がアレでちょっとなあ。raw型と<?>の場合ですよね…。inferとは書かれているけど。
2011-08-01 00:31:48@kmizu "both cases" というのは、List rawList = new ArrayList<>(); List<?> wildList = new ArrayList<>(); の両方を指していますよね。つまり、左辺に境界無しワイルドカードが来た場合
2011-08-01 00:30:02@nagise つまり、 List<?> wildList = new ArrayList<>(); のときに、 List<?> wildList = new ArrayList<Object>(); に推論されるという話なわけで、境界付きワイルドカードだけ特殊だと考えるのは
2011-08-01 00:31:12@nagise ちょっと難しいのではないかと。あと、型の推論結果について、"This result is implied by the rules contained in §15.12.2." というのも見逃してはいけないポイントかと。
2011-08-01 00:32:16@kmizu んー。僕の目下の疑問は、その「推論」が不可視である点なんです。推論が行われていようと、実は行われていなかろうと、それを観測できないんですよ。
2011-08-01 00:33:05