<?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>ジェネリックなクラスの階層を遡って適用された具象型を得る</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>0</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>1</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>3</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>5</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>0</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>0</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><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスを最大限活用するための設計技法 Strategyパターン編</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/30/140375.aspx</link><pubDate>Fri, 30 May 2008 17:59:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/30/140375.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/140375.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/30/140375.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/140375.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/140375.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/28/139846.aspx"&gt;前回&lt;/a&gt;は振りだけでしたが、
今回からデザインパターンとの絡ませ方を紹介してきます。&lt;/p&gt;

&lt;h4&gt;Strategyパターンの実例&lt;/h4&gt;

&lt;p&gt;Strategyパターンの実例として
&lt;a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/util/Comparator.html"&gt;java.lang.Comparator&lt;/a&gt;
および
&lt;a href="http://msdn.microsoft.com/ja-jp/library/8ehhxeaf.aspx"&gt;System.Collections.Generic.IComparer&lt;/a&gt;
によるソートを取り上げます。
&lt;/p&gt;

&lt;p&gt;Strategyパターンによって切り替わるのは、ソートのアルゴリズムではなく、二つのオブジェクトの比較方法です。
ここではUserというオブジェクトを想定してみます。&lt;/p&gt;

&lt;p&gt;Java&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;User&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="#000000"&gt;String&amp;nbsp;name;&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;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;age;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;このUserのListがあるとして、これを名前(name)順にソートするのか、あるいは年齢(age)順に
ソートするのかといったことをStrategyパターンで切り替えるわけです。&lt;/p&gt;

&lt;p&gt;そのためのStrategyのインターフェースが先に挙げた
&lt;a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/util/Comparator.html"&gt;java.lang.Comparator&lt;/a&gt;
および
&lt;a href="http://msdn.microsoft.com/ja-jp/library/8ehhxeaf.aspx"&gt;System.Collections.Generic.IComparer&lt;/a&gt;
となるわけです。&lt;/p&gt;

&lt;p&gt;これらの実装クラスをStrategyとしてソートのメソッドに渡すことで、ソート処理の動きを切り替えることが出来ているわけです。&lt;/p&gt;
&lt;p&gt;Java Strategyの実装&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;UserNameComparator&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;Comparator&amp;lt;&lt;strong&gt;User&lt;/strong&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;&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;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;compare&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;&lt;strong&gt;User&amp;nbsp;user1,&amp;nbsp;User&amp;nbsp;user2&lt;/strong&gt;&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;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;user1.name.compareTo&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;user2.name&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;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Java ソート処理の呼び出し&lt;code&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;List&amp;lt;User&amp;gt;&amp;nbsp;list&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;User&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;ABC&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;10&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;BCD&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;12&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;CDE&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;8&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Collections.sort&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;list,&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;&lt;strong&gt;UserNameComparator&lt;/strong&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;C# Strategyの実装&lt;code&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;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;UserNameComparer&amp;nbsp;:&amp;nbsp;IComparer&amp;lt;&lt;strong&gt;User&lt;/strong&gt;&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;{&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;public&amp;nbsp;&lt;/b&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;Compare&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;&lt;strong&gt;User&amp;nbsp;user1,&amp;nbsp;User&amp;nbsp;user2&lt;/strong&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;&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;&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;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;user1.name.CompareTo&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;user2&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;&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;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;C# ソート処理の呼び出し&lt;code&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;User&amp;gt;&amp;nbsp;list&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;List&amp;lt;User&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;ABC&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;10&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;BCD&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;12&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.add&lt;/font&gt;&lt;font color="#000000"&gt;(&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;User&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;CDE&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;8&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;list.Sort&lt;/font&gt;&lt;font color="#000000"&gt;(&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;&lt;strong&gt;UserNameComparer&lt;/strong&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;h4&gt;ジェネリクスによる具象化&lt;/h4&gt;

&lt;p&gt;さて、ここでジェネリクスによる具象化がどこで行われるかを見てみましょう。&lt;/p&gt;

&lt;p&gt;まずはソート処理を呼び出す部分。こちらではListに入るオブジェクト型を明示しています。
ここのソースコード状ではジェネリクス型パラメータは具象化されているわけです。&lt;/p&gt;

&lt;p&gt;そして呼び出されたソート処理の中身、つまるところクラスライブラリ内では当然ながら
StrategyであるComparatorやIComparerのジェネリクス型は具象化されない状態で処理されます。
ですから、ソートのアルゴリズム中ではListのオブジェクトが何型かを意識してはいけません。
動的にinstanceofとかで調べることはできますが、覗き見はしてはダメ。&lt;/p&gt;

&lt;p&gt;そして、実際のStrategyの具象型部分。ここでは比較を行うオブジェクトは具体化されています。
型が具体化されているのでキャストなどは不要で、Listに格納される型に合わせた処理をそのまま記述できます。&lt;/p&gt;

&lt;h4&gt;キセルのような中抜きの抽象化&lt;/h4&gt;

&lt;p&gt;ジェネリクスがない場合、Strategyの実装クラスでキャストしなくてはなりません。
事実、ジェネリクス搭載前のJavaではそのようにコードを書かざるを得ませんでした。&lt;/p&gt;

&lt;p&gt;ソートのアルゴリズムを抽象化したら、比較のアルゴリズムの引数まで抽象型(Object型)に
なってしまっていたのです。これをジェネリクスによって具象化することができるようになりました。&lt;/p&gt;

&lt;p&gt;中間のソートのアルゴリズム中では型は抽象的に、呼び出し部分およびStrategyの実装部分では具体的に
というわがままな抽象化がジェネリクスによって可能となったのです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/140375.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>ジェネリクスを最大限活用するための設計技法</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/28/139846.aspx</link><pubDate>Wed, 28 May 2008 23:32:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/28/139846.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/139846.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/28/139846.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/139846.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/139846.aspx</trackback:ping><description>&lt;p&gt;先日の自己言及するジェネリクス(&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;ジェネリクスの具象型の与え方は2通りあり、そしてそれは、違う用途で用いられる、ということです。&lt;/p&gt;

&lt;h4&gt;コレクション型で用いられるジェネリクス&lt;/h4&gt;

&lt;p&gt;JavaやC#のジェネリクスで馴染みが深いのはコレクションAPIでのジェネリクスでしょう。
つまるところJavaの&lt;a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/util/List.html"&gt;java.util.List&lt;/a&gt;や、
C#の&lt;a href="http://msdn.microsoft.com/ja-jp/library/6sh2ey19(VS.80).aspx"&gt;System.Collections.Generic.List&lt;/a&gt;
といったクラスです。&lt;/p&gt;

&lt;p&gt;これらのクラスは通常、newする際にジェネリクスの型パラメータに具象型を指定して具体化させます。&lt;/p&gt;

&lt;p&gt;Java&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;C#&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;List&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;このタイプの使い方はよく用いられているようですが、もうひとつのジェネリクス型を具象化させる方法を使えていますか？&lt;/p&gt;

&lt;h4&gt;継承を用いた具象化&lt;/h4&gt;

&lt;p&gt;ジェネリクス型を具象化させるもうひとつの方法はクラスの継承の際に型を渡す手法です。&lt;/p&gt;

&lt;p&gt;Java&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;StringList&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;ArrayList&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;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;...&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;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;StringList&amp;nbsp;:&amp;nbsp;List&amp;lt;String&amp;gt;&lt;/font&gt;&lt;br /&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;...&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;サンプルではListの継承としていますが、通常こちらの使い方はコレクションAPIに対しては使われません。
オブジェクト指向の継承の機能を利用して再利用可能な抽象化を行おうとする際に用います。&lt;/p&gt;

&lt;h4&gt;デザインパターンとの併用&lt;/h4&gt;

&lt;p&gt;この手法はデザインパターンと併用することでクラス設計に深みが生まれます。
相性の良いGoFデザインパターンには以下のものが挙げられると思います。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ポリモフィズムで条件分岐するパターン（Strategy、State、Abstract Factory）
&lt;li&gt;複雑な生成を隠ぺいするパターン(Builder、Factory Method)
&lt;li&gt;構造に纏わるパターンの定石部分の再利用(Composite、Visitor)
&lt;/ul&gt;

&lt;p&gt;ここに挙げたデザインパターン以外にも適用可能だとは思いますが、特徴的なのは上記のものだと考えています。
これらのデザインパターンでの具体的なジェネリクスの使い方は次回以降で詳しく掘り下げてみたいと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/139846.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>自己言及するジェネリクス C#版</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/26/139486.aspx</link><pubDate>Mon, 26 May 2008 22:26:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/26/139486.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/139486.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/26/139486.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/139486.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/139486.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx"&gt;自己言及するジェネリクス&lt;/a&gt;をC#でも書いてみました。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
namespace Sample&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class HogeA&amp;lt;H&amp;gt; where H : HogeA&amp;lt;H&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public H GetHoge(){return null;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class HogeB : HogeA&amp;lt;HogeB&amp;gt;{}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class Test&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static void Main(String[] args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HogeB hogeB = new HogeB();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HogeB hogeB2 = hogeB.GetHoge();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;やってることは一緒ですね。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/139486.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>自己言及するジェネリクス</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx</link><pubDate>Sun, 25 May 2008 18:06:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/139308.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/25/139308.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/139308.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/139308.aspx</trackback:ping><description>&lt;p&gt;先日、&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/20/138700.aspx"&gt;Strategyのインスタンスをenumで扱う&lt;/a&gt;で取り上げたようにJavaのenumはメソッドを宣言することができます。JavaSE5.0でenumを追加する際、既存の型システムを利用して作られているため、Javaのenumはクラスなのです。&lt;/p&gt;

&lt;p&gt;このenumの親クラスとなるのがjava.lang.Enumクラスなのですが、宣言が変わっていて、ジェネリクスの型パラメータが自身の拡張なのですね。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#000000"&gt;Enum&amp;lt;E&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;Enum&amp;lt;E&amp;gt;&amp;gt;&lt;/font&gt;&lt;/code&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;Hoge&amp;lt;H&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;H&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;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;Hoge&amp;lt;Hoge&amp;lt;Hoge&amp;lt;...&amp;gt;&amp;gt;&amp;gt;&amp;nbsp;hoge&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;Hoge&amp;lt;Hoge&amp;lt;Hoge&amp;lt;...&amp;gt;&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="#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;a href="http://blogs.wankuma.com/nagise/archive/2008/05/25/139257.aspx"&gt;自作のHEXのフレームワーク&lt;/a&gt;の
リファクタリングをやっていて似たような構造が出来た時に、こうした自己言及するジェネリクスの使い方がわかりました。&lt;/p&gt;

&lt;p&gt;この自己言及型のジェネリクスは&lt;strong&gt;継承する際に型パラメータに具象型を渡す&lt;/strong&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;Hoge&amp;lt;H&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;H&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;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;H&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;&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;&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;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&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;Piyo&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;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;Piyo&amp;nbsp;piyo&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;Piyo&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;strong&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Piyo&amp;nbsp;piyo2&amp;nbsp;=&amp;nbsp;piyo.hoge&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/strong&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#hoge()メソッドは戻り型をHogeではなく、ジェネリクスでHとしています。
そのため、Hogeの継承型であるPiyoのhoge()メソッドは戻り型がHogeではなくて&lt;strong&gt;Piyo型になります&lt;/strong&gt;。
サンプルソース中の強調部分を見てください。キャストしていませんよね。&lt;/p&gt;
&lt;p&gt;もしもメソッドがHoge型を返すようにしているような場合では
Hogeの子クラスであるPiyo型をreturnすることはできますが、受け手、つまりメソッドの呼び出し元では
キャストを行わないと代入ができません。そして、そのキャストはダウンキャストであって型安全ではありません。&lt;/p&gt;

&lt;p&gt;このように、自身のインスタンスを返すメソッドがあったとして、そのクラス(ここではHoge)継承された場合に
そのメソッドが継承した子クラス(ここではPiyo)を返すようにすることができるのです。&lt;/p&gt;

&lt;p&gt;これは、自信のインスタンスを直接返す他、自信の型をジェネリクスとして用いているメソッドなどを定義する場合にも使えます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/139308.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>