<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>ジェネリクス</title><link>http://blogs.wankuma.com/nagise/category/1924.aspx</link><description>ジェネリクス</description><managingEditor>凪瀬</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>凪瀬</dc:creator><title>複数通貨のMoneyをジェネリクスで作る</title><link>http://blogs.wankuma.com/nagise/archive/2009/05/19/173180.aspx</link><pubDate>Tue, 19 May 2009 00:54:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2009/05/19/173180.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/173180.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2009/05/19/173180.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/173180.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/173180.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://kanazawa-process.g.hatena.ne.jp/katzchang/20090517/1242513168"&gt;Kanazawa.process&lt;/a&gt;では&lt;a href="http://d.hatena.ne.jp/asin/4894717115"&gt;テスト駆動開発入門&lt;/a&gt;を読んで、テスト駆動開発を学びました。その本でのテスト駆動開発のサンプルとして挙がっていたテーマは複数通貨のMoneyを作るというものでした。&lt;/p&gt;

&lt;p&gt;Dollarという米ドルを表現するオブジェクトを作り、Francというスイス・フランを表すオブジェクトを作り、そしてMoneyというオブジェクトに統合していくというリファクタリングの過程を経ています。&lt;/p&gt;

&lt;p&gt;これをジェネリクスを使って設計したらどうなるでしょうか。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;abstract&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;gt;&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;abstract&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;nbsp;add&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;?&amp;gt;&amp;nbsp;m&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Moneyオブジェクトに演算用のメソッドadd()を定義します。引き算や掛け算など要求に合わせて各種用意するといいでしょう。&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;gt;&amp;gt;
という型変数の宣言方法は&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx"&gt;自己言及するジェネリクス&lt;/a&gt;の稿で
取り上げた手法です。add()の戻り型をTとしておくことで具象型自身の型を返させることができます。&lt;/p&gt;

&lt;p&gt;これをDollarやFrancでオーバーライドして実装します。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Dollar&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;Dollar&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#646464"&gt;@Override&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Dollar&amp;nbsp;add&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;?&amp;gt;&amp;nbsp;m&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;...&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;こうすることで、Dollarのadd()はDollar型で返るわけです。
しかし、これだけだとDollarやFrancといった通貨単位ごとにadd()の実装を施さねばなりません。
protectedなファクトリーメソッドを用意して、オブジェクトの生成を具象型に委譲することで
スーパークラスであるMoney型で統一的にadd()を記述することができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;abstract&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;T&amp;gt;&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;為替レート&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Map&amp;lt;Class&amp;lt;?&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;?&amp;gt;&amp;gt;,&amp;nbsp;Map&amp;lt;Class&amp;lt;?&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;?&amp;gt;&amp;gt;,&amp;nbsp;Double&amp;gt;&amp;gt;&amp;nbsp;rateMap;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;値&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;protected&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;double&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;value;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;加算メソッドの共通実装&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;nbsp;add&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Money&amp;lt;?&amp;gt;&amp;nbsp;m&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;double&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;rate&amp;nbsp;=&amp;nbsp;rateMap.get&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;.getClass&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;.get&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;m.getClass&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;getInstance&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;.value&amp;nbsp;+&amp;nbsp;m.value&amp;nbsp;*&amp;nbsp;rate&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;具象型の生成&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;protected&amp;nbsp;abstract&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;nbsp;getInstance&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;double&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;value&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;コンストラクタ&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;protected&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Money&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;double&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;value&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;.value&amp;nbsp;=&amp;nbsp;value;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;こうした手法で通貨単位ごとに型を作って何が嬉しいかと言えば、ドル建てである場所にスイス・フランの型が紛れ込んだ場合に
コンパイルエラーにすることができるという点です。&lt;/p&gt;

&lt;p&gt;設計にはいろんな手法がありますし、それぞれにメリット、デメリットがあるので要求に合わせて柔軟に選べるようにしたいものですね。&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/173180.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>大阪勉強会#28 ジェネリクスを使おう！</title><link>http://blogs.wankuma.com/nagise/archive/2009/03/22/170057.aspx</link><pubDate>Sun, 22 Mar 2009 22:28:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2009/03/22/170057.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/170057.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2009/03/22/170057.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/170057.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/170057.aspx</trackback:ping><description>&lt;p&gt;春分の日に大阪勉強会#28でセッションやってきました。&lt;/p&gt;

&lt;p&gt;今回はジェネリクスということで難度の高いネタなんですが、狙いとしてはジェネリクスを使えるようになった先の世界はこんな感じだよ、というのが伝えられたらいいなということで、細かいところはおいておいて設計とかでこんな感じで役立つよという話をメインにしていました。後半部分ですね。&lt;/p&gt;

&lt;p&gt;僕としては自重なしにマニアックなネタをしゃべったんですっきり。セッション聞いてもやもやした人は勉強してすっきりさせてください（鬼&lt;/p&gt;

&lt;h4&gt;ジェネリックメソッド&lt;/h4&gt;

&lt;p&gt;ジェネリックメソッドについては意図的にスルーしていたのですが、知りたいと言う人のためにさらっと説明しておくと、型変数がメソッドになっただけです。型変数にまつわる制約などはジェネリッククラスの場合の型変数と変わりませんね。&lt;/p&gt;

&lt;p&gt;Javaのジェネリックメソッドで特記するべき点は型推論が効くと言う点なのですが、これがまたえらいややこしい話題なのでこれまたセッションではちょっと説明しきれない代物ですね。もっとも私もジェネリクスの型推論については語れるほど理解できていませんし。&lt;/p&gt;

&lt;h4&gt;キャストのシンタックスシュガー&lt;/h4&gt;

&lt;p&gt;ジェネリクスを「キャストのシンタックスシュガー」と言った人がいたと記憶していますが、この表現では大事なことを見落としています。確かにキャストの発生する場所全てで漏れなく確実にキャストを入れれるのであれば、ジェネリクスを使った場合と同じ動きをするプログラムになるのですが、「漏れなく確実に」がとても難しいのですね。&lt;/p&gt;

&lt;p&gt;このキャストという横断的関心事、つまるところアスペクト指向的なテーマをコンパイル時の全走査で解決しているというのがJavaのジェネリクスです。大事なのは「漏れなく確実に」という部分。「キャストのシンタックスシュガー」という表現ではこの一番肝心なところが伝わらないので表現としてはイマイチではないでしょうか。&lt;/p&gt;

&lt;h4&gt;ソースコードとか&lt;/h4&gt;

&lt;p&gt;サンプルのソースコードとかはやっつけで作ってたんで綺麗にまとめてWeb化したいところですね。C#版とかScala版とかを手伝ってくれる人がいたら歓迎します。&lt;/p&gt;

&lt;h4&gt;ジェネリクス関連エントリ&lt;/h4&gt;

&lt;p&gt;過去に書いたジェネリクス関連エントリがありますので参考にしてください。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.wankuma.com/nagise/category/1924.aspx?Show=All"&gt;凪瀬blog - ジェネリクス&lt;/a&gt;
&lt;/ul&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/170057.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>再帰型のジェネリクス型変数の境界</title><link>http://blogs.wankuma.com/nagise/archive/2009/01/23/166722.aspx</link><pubDate>Fri, 23 Jan 2009 23:45:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2009/01/23/166722.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/166722.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2009/01/23/166722.aspx#Feedback</comments><slash:comments>614</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/166722.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/166722.aspx</trackback:ping><description>&lt;p&gt;先日ジェネリクスで引っ掛かった点をメモ。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx"&gt;自己言及するジェネリクス&lt;/a&gt;で述べたような具象型に具象型自身の型を扱わせることをもくろんだ型を作った場合の話。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;GenericsTest&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;abstract&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;T&amp;gt;&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;A&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;A&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;B&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;A&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;C&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;A&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;X1&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;T&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;X2&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;?&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;X3&amp;lt;T&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;S&amp;lt;?&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;super&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;main&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;String&lt;/font&gt;&lt;font color="#000000"&gt;[]&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;args&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X1&amp;lt;A&amp;gt;&amp;nbsp;x1A;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X1&amp;lt;B&amp;gt;&amp;nbsp;x1B;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;NG&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X1&amp;lt;C&amp;gt;&amp;nbsp;x1C;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;NG&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X2&amp;lt;A&amp;gt;&amp;nbsp;x2A;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X2&amp;lt;B&amp;gt;&amp;nbsp;x2B;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X2&amp;lt;C&amp;gt;&amp;nbsp;x2C;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X3&amp;lt;A&amp;gt;&amp;nbsp;x3A;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X3&amp;lt;B&amp;gt;&amp;nbsp;x3B;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;OK&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;X3&amp;lt;C&amp;gt;&amp;nbsp;x3C;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;NG&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sが親となるクラスで&amp;lt;T extends S&amp;lt;T&amp;gt;&amp;gt;という境界をもつジェネリクス型変数Tを持ちます。
サブクラスであるAはこのTにA自身を渡すことで、Sクラス中にT型で宣言した部分をA型にすることができるのですね。&lt;/p&gt;

&lt;p&gt;そのA型を継承したクラスBを考えた場合、BはS&amp;lt;A&amp;gt;を継承しているのでB extends S&amp;lt;A&amp;gt;ということになります。
なのでX1の境界&amp;lt;T extends S&amp;lt;T&amp;gt;&amp;gt;に合致しません。&lt;/p&gt;

&lt;p&gt;こうした型を受け入れれるように規制を緩めたのがX2で&amp;lt;T extends S&amp;lt;?&amp;gt;&amp;gt;としています。
この場合、穴ができてCのようなAのサブクラスでもないのにSの型変数TにAを渡したような歪なクラスを宣言した場合に許容されてしまいます(x2C部分)。
クラスS中に表現されるTを具象型自身にするという趣旨からすればこのような歪な型は許容したくありません。
T型の戻り値のメソッドでreturn this;とか書きたいわけです。&lt;/p&gt;

&lt;p&gt;なので正確に型を表現するとしたならば&amp;lt;T extends S&amp;lt;? super T&amp;gt;&amp;gt;とします。
これでAはもちろん、AのサブクラスであるBも許容され、歪なCは弾くことができます。&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/166722.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスの代入互換の補足</title><link>http://blogs.wankuma.com/nagise/archive/2009/01/04/165571.aspx</link><pubDate>Sun, 04 Jan 2009 18:06:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2009/01/04/165571.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/165571.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2009/01/04/165571.aspx#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/165571.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/165571.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/08/20/153557.aspx"&gt;ジェネリクスの代入を理解する その２&lt;/a&gt;に以下の質問を頂きました。&lt;/p&gt;

&lt;p&gt;&lt;blockquote&gt;
インタフェースIFをAが実装しているとし、&lt;br&gt;
A←B←Cの関係はそのままの場合で下記処理をコンパイルしたとします。&lt;br&gt;
List&amp;lt;? super B&amp;gt; list = new ArrayList&amp;lt;IF&amp;gt;&lt;br&gt;
list.add(new B()); //1&lt;br&gt;
list.add(new A()); //2&lt;br&gt;
list.add(new C()); //3&lt;br&gt;
&lt;br&gt;
この場合も2はエラーとなってしまいます。 &lt;br&gt;
ArrayList&amp;lt;IF&amp;gt;にAをaddしても矛盾しないと思うのですが、&lt;br&gt;
これは何故なのでしょうか？？ 
&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;変数list はList&amp;lt;? super B&amp;gt;型ですから、ArrayList&amp;lt;B&amp;gt;型を代入することができますよね。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;? super B&amp;gt; list = new ArrayList&amp;lt;IF&amp;gt;();&lt;br&gt;
list = new ArrayList&amp;lt;B&amp;gt;();&lt;br&gt;
list.add(new A());&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;としたらどうなるでしょうか？&lt;br&gt;
ArrayList&amp;lt;B&amp;gt;にAをaddすることになりますね。落ち着いて考えてみてください。List&amp;lt;? super B&amp;gt; list = new ArrayList&amp;lt;A&amp;gt;();のケースと同じです。&lt;/p&gt;

&lt;p&gt;コンパイルによる静的な型チェックは、いつ変数listにどういう型を代入されたかを追跡しません。&lt;br&gt;
なので代入して矛盾が発生する可能性がある場合にすべてコンパイルエラーとします。&lt;/p&gt;

&lt;p&gt;古いエントリになりますが、&lt;a href="http://blogs.wankuma.com/nagise/archive/2007/08/04/88855.aspx"&gt;ジェネリクスと代入と落とし穴2&lt;/a&gt;も併せてご覧ください。&lt;/p&gt;

&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/165571.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリックなクラスの階層を遡って適用された具象型を得る</title><link>http://blogs.wankuma.com/nagise/archive/2008/10/29/160075.aspx</link><pubDate>Wed, 29 Oct 2008 00:50:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/10/29/160075.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/160075.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/10/29/160075.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/160075.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/160075.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/10/13/158708.aspx"&gt;イレイジャではジェネリクスの何が消えるのか&lt;/a&gt;にて親クラスを継承する際に投入しているジェネリクス型パラメータはclassの情報として残っていることを述べました。&lt;/p&gt;

&lt;p&gt;これを利用すると、&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;A&amp;lt;X&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;B&amp;lt;Y&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;A&amp;lt;Y&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;C&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;B&amp;lt;String&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;といった継承階層があった場合に、C.classからA.classの&amp;lt;X&amp;gt;にどのような具象型が適用されているのか(上記例ではString型)をリフレクションで取得することができます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Aの型パラメータのプレースホルダ&amp;lt;X&amp;gt;を取得&lt;/li&gt;
&lt;li&gt;Bでsuper-classの型パラメータに渡されたTypeを取得&lt;/li&gt;
&lt;li&gt;2のTypeが具象型ではなく型パラメータ&amp;lt;Y&amp;gt;なのでさらにサブクラスを走査&lt;/li&gt;
&lt;li&gt;Cでsuper-classの型パラメータに渡されたTypeを取得&lt;/li&gt;
&lt;li&gt;B&amp;lt;Y&amp;gt;のYにString型が渡されていることが分かるのでA&amp;lt;X&amp;gt;のXがStringであることが分かる&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;といった感じです。型階層がいくらあるのか分からないので再帰で処理するとよいでしょう。&lt;/p&gt;

&lt;h4&gt;サンプルプログラム&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;渡された型から継承階層を登って、&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;指定の親の型の指定の名前のジェネリクス型パラメータが&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;継承の過程で何型で具現化されているかを走査して返す。&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;clazz&amp;nbsp;走査開始する型&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;targetClass&amp;nbsp;走査する対象のジェネリクス型パラメータを持つ型。&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;走査開始型の親である必要がある。&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;targetTypeName&amp;nbsp;何型で具現化されたを確認したい型パラメータのプレースホルダ名&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@return&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;具現化された型&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;T&amp;gt;&amp;nbsp;Class&amp;lt;T&amp;gt;&amp;nbsp;getGenericType&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;?&amp;gt;&amp;nbsp;clazz,&amp;nbsp;Class&amp;lt;?&amp;gt;&amp;nbsp;targetClass,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;targetTypeName&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;!targetClass.isAssignableFrom&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;clazz&lt;/font&gt;&lt;font color="#000000"&gt;))&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throw&amp;nbsp;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IllegalArgumentException&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;型&amp;#34;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;clazz.getName&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;は、型&amp;#34;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;targetClass.getName&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;を継承していません&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Stack&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt;&amp;nbsp;stack&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Stack&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;while&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;!targetClass.equals&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;clazz.getSuperclass&lt;/font&gt;&lt;font color="#000000"&gt;()))&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;stack.push&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;clazz&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;clazz&amp;nbsp;=&amp;nbsp;clazz.getSuperclass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;getGenericTypeImpl&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;clazz,&amp;nbsp;targetTypeName,&amp;nbsp;stack&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;型パラメータの具象型取得の実装。再帰処理される。&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;clazz&amp;nbsp;現在の走査対象型&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;targetTypeName&amp;nbsp;現在の走査対象のジェネリクス型パラメータ名&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;stack&amp;nbsp;現在の走査対象型以下の継承階層が積まれたStack&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@return&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;該当型パラメータの具現化された型&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#646464"&gt;@SuppressWarnings&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;unchecked&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;br /&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;T&amp;gt;&amp;nbsp;Class&amp;lt;T&amp;gt;&amp;nbsp;getGenericTypeImpl&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;?&amp;gt;&amp;nbsp;clazz,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;targetTypeName,&amp;nbsp;Stack&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt;&amp;nbsp;stack&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;TypeVariable&amp;lt;?&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;?&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;[]&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;superGenTypeAray&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;=&amp;nbsp;clazz.getSuperclass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getTypeParameters&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;走査対象の型パラメータの名称(Tなど)から宣言のインデックスを取得&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;index&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;0&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;boolean&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;existFlag&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;for&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;TypeVariable&amp;lt;?&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;?&amp;gt;&amp;gt;&amp;nbsp;type&amp;nbsp;:&amp;nbsp;superGenTypeAray&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;targetTypeName.equals&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;type.getName&lt;/font&gt;&lt;font color="#000000"&gt;()))&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;existFlag&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;break&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;index++;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;!existFlag&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throw&amp;nbsp;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IllegalArgumentException&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;targetTypeName&amp;nbsp;+&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;に合致するジェネリクス型パラメータがみつかりません&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;走査対象の型パラメータが何型とされているのかを取得&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;ParameterizedType&amp;nbsp;type&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ParameterizedType&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;clazz.getGenericSuperclass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Type&amp;nbsp;y&amp;nbsp;=&amp;nbsp;type.getActualTypeArguments&lt;/font&gt;&lt;font color="#000000"&gt;()[&lt;/font&gt;&lt;font color="#000000"&gt;index&lt;/font&gt;&lt;font color="#000000"&gt;]&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;具象型で継承されている場合&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;y&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;instanceof&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Class&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;T&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;y;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;ジェネリックパラメータの場合&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;y&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;instanceof&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;TypeVariable&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;TypeVariable&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt;&amp;nbsp;tv&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;TypeVariable&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;y;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;再帰して同名の型パラメータを継承階層を下りながら解決を試みる&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;?&amp;gt;&amp;nbsp;sub&amp;nbsp;=&amp;nbsp;stack.pop&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;getGenericTypeImpl&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;sub,&amp;nbsp;tv.getName&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;stack&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;ジェネリック型パラメータを持つ型の場合&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;if&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;y&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;instanceof&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ParameterizedType&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;ParameterizedType&amp;nbsp;pt&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ParameterizedType&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;y;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;lt;T&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;pt.getRawType&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throw&amp;nbsp;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IllegalArgumentException&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;予期せぬ型&amp;nbsp;:&amp;nbsp;&amp;#34;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;y.toString&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;&amp;nbsp;(&amp;#34;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;y.getClass&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;)&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/160075.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>イレイジャではジェネリクスの何が消えるのか</title><link>http://blogs.wankuma.com/nagise/archive/2008/10/13/158708.aspx</link><pubDate>Mon, 13 Oct 2008 20:21:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/10/13/158708.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/158708.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/10/13/158708.aspx#Feedback</comments><slash:comments>50</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/158708.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/158708.aspx</trackback:ping><description>&lt;p&gt;Javaのジェネリクスはコンパイル時に解決され、classファイルになった時にはジェネリクスの型情報は残されていません。そのためイレイジャ（型消去：type erasure）方式と呼ばれます。&lt;/p&gt;

&lt;p&gt;と、ひとくちで言っても意味がよく分からないのでちょっと掘り下げてみましょう。&lt;/p&gt;

&lt;h4&gt;インスタンスからジェネリクスの型情報は拾えない&lt;/h4&gt;

&lt;p&gt;リフレクションを用いたとしても、インスタンスからジェネリクス型パラメータが何であるかを取得することはできません。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#000000"&gt;List&amp;lt;String&amp;gt;&amp;nbsp;stringList&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ArrayList&amp;lt;String&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;のような変数stringListがあったとして、ここから&amp;lt;String&amp;gt;を取得するということができないのです。これが消えてしまった部分。&lt;/p&gt;

&lt;p&gt;この変数stringListに対する各種操作において、その型の安全はコンパイル時に精査され、
実行時にはあくまでObject型引数のメソッドを通したやりとりで動くのです。&lt;/p&gt;

&lt;h4&gt;クラス宣言に関わるジェネリクス型情報は拾える&lt;/h4&gt;

&lt;p&gt;しかし、型の宣言に関する部分はリフレクションで拾うことができます。ここが混乱する部分ですね。&lt;/p&gt;

&lt;p&gt;&lt;ul&gt;
&lt;li&gt;親クラスを継承する際に投入しているジェネリクス型パラメータ
&lt;li&gt;インターフェースを実装する際に投入しているジェネリクス型パラメータ
&lt;li&gt;メソッドの引数・戻り値に用いられているジェネリックな型とそこに渡される型パラメータ
&lt;li&gt;フィールドに用いられているジェネリックな型とそこに渡される型パラメータ
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;といった情報は拾えるわけです。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Piyo&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Hoge&amp;lt;String&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;implements&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IHoge&amp;lt;String&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;String&amp;gt;&amp;nbsp;value;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;String&amp;gt;&amp;nbsp;get&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;this&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;.value;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;set&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;String&amp;gt;&amp;nbsp;value&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;.value&amp;nbsp;=&amp;nbsp;value;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;といったコードがあった場合、リフレクションで親クラスがHoge&amp;lt;String&amp;gt;型であることを拾えます。インターフェースも同等。
また、フィールドやメソッドの戻り値・引数がList&amp;lt;String&amp;gt;型であることも拾うことができます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/158708.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスの代入を理解する その２</title><link>http://blogs.wankuma.com/nagise/archive/2008/08/20/153557.aspx</link><pubDate>Wed, 20 Aug 2008 00:08:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/08/20/153557.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/153557.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/08/20/153557.aspx#Feedback</comments><slash:comments>216</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/153557.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/153557.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/08/18/153424.aspx"&gt;
前回&lt;/a&gt;はまず、ジェネリクス型パラメータを伴うList同士の代入互換性について述べました。&lt;/p&gt;

&lt;p&gt;今回はそれらのListのadd()メソッドとget()メソッドについて見てきたいと思います。&lt;/p&gt;

&lt;p&gt;なお、前回同様に C &lt;font color="#7f0055"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt; B,
 B &lt;font color="#7f0055"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt; A
 という継承関係があることとして以下話を進めます。&lt;/p&gt;

&lt;h4&gt;入力値の制約&lt;/h4&gt;

&lt;p&gt;前回で&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;型には
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;も
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;も
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends C&lt;/b&gt;&lt;/font&gt;&amp;gt;も代入できると述べました。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt; listBEx = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;();
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ということができるわけですね。
さて、このlistBExにadd()をしてみるとしましょう。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
listBEx.add(&lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; B());
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;実は、これがコンパイルエラーになるのです。
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;型には
B型をadd()できないのです！&lt;/p&gt;

&lt;p&gt;というのも、さきほどlistBExはArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;型で
初期化しましたね。もし、Bをadd()できるとしたら、
ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;型に
B型がadd()されてしまうことになります。これでは矛盾してしまいますね。&lt;/p&gt;

&lt;p&gt;ですから、List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;では
型の安全性が破壊されないように、add()できるのは
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;に代入可能な
List全てにadd()可能なものだけしかadd()できないように制約が掛けられます。&lt;/p&gt;

&lt;img alt="? extends Bへの代入" src="http://nagise.wankuma.com/image/generics_04.png"&gt;

&lt;p&gt;&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;の範囲と
ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;の範囲、
そしてBオブジェクトの位置を確認してみてください。
Bオブジェクトを型安全にadd()することができないのが分かるでしょうか？&lt;/p&gt;

&lt;p&gt;では&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;に対して何がadd()できるのでしょうか？&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
listBEx.add(&lt;font color="#7f0055"&gt;&lt;b&gt;null&lt;/b&gt;&lt;/font&gt;);
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;だけが可能なのです。使えませんね…。&lt;/p&gt;

&lt;p&gt;さて、add()メソッドはこのような制約があるわけですが、get()メソッドなどは普通に使えます。
この違いは何なのでしょうか？&lt;/p&gt;

&lt;p&gt;これは、&lt;strong&gt;メソッドの引数にジェネリクス型パラメータが含まれる場合に発生する制約&lt;/strong&gt;です。
引数にジェネリクス型が含まれるadd()などではこのような制約が発生し、
引数にジェネリクス型を含まないget()などでは制約は発生しません。&lt;/p&gt;

&lt;p&gt;オブジェクトに対しての入力値がジェネリクスの代入互換性に矛盾しないようにするために
存在する制約というわけなのです。&lt;/p&gt;

&lt;h4&gt;出力値の制約&lt;/h4&gt;

&lt;p&gt;List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;からの
get()は問題なく行え、B型の変数に受け取ることができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
B b = listBEx.get(0);
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;これは、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;に
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;が代入されていようが
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;が代入されていようが、
get()で取り出されるオブジェクトは「B型を継承した何か」ですから、B型に安全にキャストできるわけです。&lt;/p&gt;

&lt;p&gt;ここで、List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;を考えてみましょう。&lt;/p&gt;

&lt;p&gt;&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;には
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;や
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/font&gt;&amp;gt;を代入することができます。&lt;/p&gt;

&lt;p&gt;ということは、get()で取り出されるオブジェクトは、B型よりも上位のオブジェクト型である可能性があるわけです。
このことから、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;とした場合は
全ての型のトップに位置するObject型でしかget()したオブジェクトを受け取ることができません。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
Object o = listBSu.get(0);
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;これは前回の図を見ると分かることでしょう。再掲します。&lt;/p&gt;

&lt;img alt="階層? super B" src="http://nagise.wankuma.com/image/generics_03.png"&gt;

&lt;h4&gt;入力値の制約　再訪&lt;/h4&gt;

&lt;p&gt;List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;へのadd()はどうでしょうか？&lt;/p&gt;

&lt;img alt="? super Bへの代入" src="http://nagise.wankuma.com/image/generics_05.png"&gt;

&lt;p&gt;図を見て分かるように、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;に
代入可能な&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;や
&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/font&gt;&amp;gt;は、すべてBオブジェクトを
受け入れることができます。&lt;/p&gt;

&lt;p&gt;そのため、ジェネリクスが&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;であれば
B型をadd()することができます。&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/153557.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスの代入を理解する その１</title><link>http://blogs.wankuma.com/nagise/archive/2008/08/18/153424.aspx</link><pubDate>Mon, 18 Aug 2008 23:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/08/18/153424.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/153424.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/08/18/153424.aspx#Feedback</comments><slash:comments>3646</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/153424.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/153424.aspx</trackback:ping><description>&lt;p&gt;Javaのジェネリクスはかなり強力で、相当の型を表現できるのですが、
代償として非常に複雑なものとなっています。&lt;/p&gt;

&lt;p&gt;ややこしいのは、オブジェクト指向の部分の型の代入互換性と、
ジェネリクス型パラメータの部分の代入互換性は、表現こそ似ているものの、
その意味するところはまるで違うと言うことにあります。&lt;/p&gt;

&lt;p&gt;端的には、C &lt;font color="#7f0055"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt; B,
 B &lt;font color="#7f0055"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt; Aの関係があるとして、
型B にはサブクラスであるCをキャストなしに安全に代入することができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
B b = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; C();
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;しかし、ジェネリクス型パラメータの場合の&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt; listB = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;();
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;はコンパイルエラーとなります。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt; listBEx = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;();
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;であれば代入が可能です。
このように、同じ継承階層の型を扱うのにもかかわらず、その代入互換性が違うのですから
混乱するのはやむなしと言えましょう。&lt;/p&gt;

&lt;h4&gt;ジェネリクス型パラメータの代入互換性&lt;/h4&gt;

&lt;p&gt;ジェネリクスでは、単に型をBと表現した場合、Bの階層だけが対象となります。&lt;/p&gt;

&lt;img alt="階層B" src="http://nagise.wankuma.com/image/generics_01.png"&gt;

&lt;p&gt;図のBの階層だけが対象になります。
ですから、代入できるのは&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;型だけです。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt; listB = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;();
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;次に、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;と表現した場合、BとそのサブクラスであるCが含まれます。&lt;/p&gt;

&lt;img alt="階層? extends B" src="http://nagise.wankuma.com/image/generics_02.png"&gt;

&lt;p&gt;&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;には&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;も&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;も代入することができます。
また、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends C&lt;/b&gt;&lt;/font&gt;&amp;gt;も代入することができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt; listBEx;&lt;br&gt;
listBEx = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
listBEx = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends C&lt;/b&gt;&lt;/font&gt;&amp;gt; listCEx = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;C&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
listBEx = listCEx;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;また、ジェネリクスでは継承階層をスーパークラス側に遡る、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;という記述もできます。
この場合は、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? extends B&lt;/b&gt;&lt;/font&gt;&amp;gt;とは逆方向の範囲をカバーします。&lt;/p&gt;

&lt;img alt="階層? super B" src="http://nagise.wankuma.com/image/generics_03.png"&gt;

&lt;p&gt;この&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt;には&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;や&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/font&gt;&amp;gt;や&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super A&lt;/b&gt;&lt;/font&gt;&amp;gt;を代入することができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super B&lt;/b&gt;&lt;/font&gt;&amp;gt; listBSu;&lt;br&gt;
listBSu = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
listBSu = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
List&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;? super A&lt;/b&gt;&lt;/font&gt;&amp;gt; listASu = &lt;font color="#7f0055"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt; ArrayList&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/font&gt;&amp;gt;();&lt;br&gt;
listBSu = listASu;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;このように、&amp;lt;&lt;font color="#0000ff"&gt;&lt;b&gt;&lt;/b&gt;&lt;/font&gt;&amp;gt;の内側と外側では異なる代入規則があることをまずは明確に意識してください。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/153424.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>リフレクションでジェネリクスメソッドを扱う</title><link>http://blogs.wankuma.com/nagise/archive/2008/06/16/143906.aspx</link><pubDate>Mon, 16 Jun 2008 15:07:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/06/16/143906.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/143906.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/06/16/143906.aspx#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/143906.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/143906.aspx</trackback:ping><description>&lt;p&gt;ふと訪れた&lt;a href="http://www.gside.org/blowg/e/user/tma/entry/200806151112"&gt;blog&lt;/a&gt;で
共変戻り値(covariant return types)を話題にしていたのですが、
「コレ、JavaSE5.0からだったっけ？1.4だったような」、と思って調べるとやっぱり5.0でした orz&lt;/p&gt;

&lt;p&gt;調べるとかつのりさんところ(
&lt;a href="http://blogs.wankuma.com/kacchan6/archive/2007/04/18/71891.aspx"&gt;共変戻り値&lt;/a&gt;)で書いているなぁ…。
自分の中でなぜか1.4だと思い込んでいる様子。この記憶はどこからやってきたのか…。&lt;/p&gt;

&lt;p&gt;このあたりを見て、そういえばジェネリクスとリフレクションの話題があったなぁと思いだしたのでひとつ小噺を。&lt;/p&gt;

&lt;h4&gt;ジェネリクスの具象化とメソッドシグニチャ&lt;/h4&gt;

&lt;p&gt;さて、気を取り直して、この共変なオーバーライドですが、ジェネリクスの実装にはなくてはならないものです。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;interface&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Sample&amp;lt;T&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;nbsp;hoge&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;piyo&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;T&amp;nbsp;t&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;といったジェネリクス型パラメータを持つinterfaceがあったとして&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;SampleImpl&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;implements&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Sample&amp;lt;String&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;hoge&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;null&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;piyo&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;t&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;というようにimplements時にStringとすると、hoge()の戻り型はStringクラスになるわけです。
これは共変な戻り値になっているわけですね。&lt;/p&gt;

&lt;h4&gt;ジェネリクスのメソッドをリフレクションしたら&lt;/h4&gt;

&lt;p&gt;さて、先ほどのコード、piyo()が&lt;strong&gt;オーバーロード&lt;/strong&gt;になっているのがわかりますか？&lt;/p&gt;

&lt;p&gt;インターフェースの段階ではジェネリクス型パラメータのTが引数とされていました。
これは実際的にはObject型となってしまうのですが、そうするとSampleImplのpiyo(String)は
オーバーライドではなくオーバーロードになってしまいます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#000000"&gt;SampleImpl&amp;nbsp;impl&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;SampleImpl&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Method&amp;nbsp;m&amp;nbsp;=&amp;nbsp;impl.getClass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getMethod&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;piyo&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;Object.&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;m.invoke&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;impl,&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;param&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ところが、上記のようにリフレクションでpiyo(Object)を呼び出すと、ちゃんとpiyo(String)が実行されます。
これはどうしたことか！？&lt;/p&gt;

&lt;p&gt;作られるclassの中をのぞいてみると面白いことがわかります。&lt;/p&gt;

&lt;code&gt;
  // Method descriptor #19 (Ljava/lang/String;)V&lt;br&gt;
  // Stack: 0, Locals: 2&lt;br&gt;
  public void piyo(java.lang.String t);
&lt;/code&gt;

&lt;code&gt;
  // Method descriptor #22 (Ljava/lang/Object;)V&lt;br&gt;
  // Stack: 2, Locals: 2&lt;br&gt;
  public bridge synthetic void piyo(java.lang.Object arg0);
&lt;/code&gt;

&lt;p&gt;引数がStringのものと、Objectのものとふたつ作られているんですね。
"bridge synthetic"という修飾がついています。
この元となったinterfaceのメソッドシグネチャ(メソッドを特定するためのメソッド名と引数型の組み合わせのこと)と同等のシグネチャで宣言されるメソッドが
ブリッジとなってpiyo(String)を呼び出しているのです。&lt;/p&gt;

&lt;p&gt;このため、ジェネリクスをimplementsする際に具現化していても、interfaceや抽象クラスで宣言された
メソッドシグニチャを使ってMethodを取得してinvokeすることができるのです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/143906.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスを最大限活用するための設計技法 Stateパターン編</title><link>http://blogs.wankuma.com/nagise/archive/2008/06/05/141783.aspx</link><pubDate>Thu, 05 Jun 2008 21:17:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/06/05/141783.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/141783.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/06/05/141783.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/141783.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/141783.aspx</trackback:ping><description>&lt;p&gt;今回はStateパターン編です。
Stateパターンはオブジェクト指向のポリモフィズムで動きを切り替えるという点で前回の
&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/30/140375.aspx"&gt;Strategyパターン&lt;/a&gt;と同じです。&lt;/p&gt;

&lt;p&gt;ただし、Stateパターンはそのインスタンス自身が「状態」を表現するという点で異なります。&lt;/p&gt;

&lt;h4&gt;電卓のUIのStateを作る&lt;/h4&gt;

&lt;p&gt;まず、Stateの使いどころですが、ここでは以前にわんくま同盟で取り上げられた
&lt;a href="http://blogs.wankuma.com/aqua/archive/2007/06/27/82456.aspx"&gt;電卓&lt;/a&gt;を例にしてみましょう。&lt;/p&gt;

&lt;p&gt;επιστημηさんのところに
&lt;a href="http://blogs.wankuma.com/episteme/archive/2007/07/12/84809.aspx"&gt;電卓を状態遷移で捉える&lt;/a&gt;
話題がでていたのですが、この状態遷移というのがStateパターンの使いどころになります。&lt;/p&gt;

&lt;p&gt;&lt;blockquote&gt;
&lt;table border="1"&gt;
&lt;caption&gt;電卓基本動作の状態遷移表&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;th&gt;&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/th&gt;
&lt;th&gt;&lt;font color="#008000"&gt;数値入力状態&lt;/font&gt;&lt;/th&gt;
&lt;th&gt;&lt;font color="#ffa500"&gt;数式作成状態&lt;/font&gt;&lt;/th&gt;
&lt;th&gt;&lt;font color="#0000ff"&gt;計算結果表示状態&lt;/font&gt;&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;数字入力&lt;/th&gt;

&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#008000"&gt;数値入力状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#008000"&gt;数値入力状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#008000"&gt;数値入力状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#008000"&gt;数値入力状態&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;

&lt;th&gt;演算子入力&lt;/th&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ffa500"&gt;数式作成状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ffa500"&gt;数式作成状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ffa500"&gt;数式作成状態&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;th&gt;'='入力&lt;/th&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#0000ff"&gt;計算結果表示状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#0000ff"&gt;計算結果表示状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#0000ff"&gt;計算結果表示状態&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;th&gt;'C'入力&lt;/th&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;
&lt;td&gt;なにかする&lt;br&gt;→&lt;font color="#ff0000"&gt;初期状態&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;この、「初期状態」「数値入力状態」「数式作成状態」「計算結果表示状態」がStateパターンでは
オブジェクトのインスタンスで表現されます。
そして、そのクラスには「数字入力」「演算子入力」「'='入力」「'C'入力」の4つのメソッドが定義されます。&lt;/p&gt;

&lt;p&gt;Java&lt;code&gt;
&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@param&amp;nbsp;&lt;/font&gt;&lt;font color="#7f7f9f"&gt;&amp;lt;R&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;Stateの具象型&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;interface&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;State&amp;lt;R&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;State&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;数値の入力&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@return&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;遷移するState.&amp;nbsp;以下同じ&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputNumber&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;num&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;演算子の入力&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputOperation&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Operation&amp;nbsp;ope&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;'='の入力&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputEquale&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;'C'の入力&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputClear&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;C#&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;interface&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;State&amp;lt;R&amp;gt;&amp;nbsp;where&amp;nbsp;R&amp;nbsp;:&amp;nbsp;State&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;数値の入力&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;///&amp;nbsp;&amp;lt;returns&amp;gt;遷移するState.&amp;nbsp;以下同じ&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputNumber&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;num&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;演算子の入力&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputOperation&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Operation&amp;nbsp;ope&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;'='の入力&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputEquale&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;'C'の入力&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;R&amp;nbsp;onInputClear&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;より抽象的にすることで再利用性を持たせる&lt;/h4&gt;

&lt;p&gt;通常のStateパターンだと、この時点で具象型を用いるのでジェネリクスの出番はないところですが、
&lt;strong&gt;電卓と同じユーザインターフェースを持つ別のアプリケーションを作れるように&lt;/strong&gt;ジェネリクスで
抽象化しておきます。&lt;/p&gt;

&lt;p&gt;ご覧の通り、各メソッドは処理をした上で次に遷移するべきStateを返すようになっています。
このときに自信の型を返したいので自己言及するジェネリクス(
&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx"&gt;Java版&lt;/a&gt;、
&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/26/139486.aspx"&gt;C#版&lt;/a&gt;)
で取り上げた手法を用います。&lt;/p&gt;

&lt;p&gt;これらの実装を作る際にはジェネリクス(サンプルソースのR)を具象化するわけですが、この型は
電卓用であれば電卓用、同一UIを用いた別の何かであればそれ用に独自に拡張します。
&lt;strong&gt;電卓用のStateと別の何かのStateは混同して利用されることはありません&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;つまり、このUIを共通に提供するような再利用性の高いフレームワークを設計する場合でないと、
このようなStateパターンの多様な拡張性を持たせると言う設計は活きてこないのです。&lt;/p&gt;

&lt;p&gt;逆に、このようなジェネリクスを活用することで、今まで再利用が不可能だと思っていたパーツを
再利用可能な形でライブラリとすることができます。&lt;/p&gt;

&lt;h4&gt;補足&lt;/h4&gt;

&lt;p&gt;Javaの場合はさらに
&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/20/138700.aspx"&gt;Strategyのインスタンスをenumで扱う&lt;/a&gt;
で取り上げたように、Stateのインスタンスをenum化することができます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/141783.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>