さくらんぼのlambda日記

lambdaちっくなことからゲーム開発までいろいろ書きます。

genericsが分かってなかった話

C++のtemplateとJavaのgenericsは大分違う。

  • templateはexpansionで解釈される。genericsはErasureで解釈される
  • templateでは引数として定数値を与えることができる、genericsでは出来ない
  • genericsではList> とか書ける
  • templateは型別にバイナリを生成するためコードサイズが肥大化する(code bloat)。

genericsは基本的に型安全のみを考慮して作られているので
変なことが出来ないようになってる感じですね。

http://d.hatena.ne.jp/amachang/20080415/1208229209


この辺りの話はJava言語仕様にものってた気がするので
帰ったらチェックします。

特に

public static <T, S extends T> T cast(S o) { return (T) o; }

この辺り。

あと自己言及的なtemplateをgenericsで記述しても問題無く動作するようですね。

ソースの例は続きのあとに。

public class GenericClass<T extends GenericClass<T>> {
	      private T value;

	      public T getValue() {
	      return value;
	      }
	      public void setValue(T c) {
	      value = c;
	      }

	      public void method() {
	      as_derived().method();
	      }
	      public GenericClass<T> as_derived() {
		return this;
		}
		public T hoge() {
		return (T) this;
		}

}

public class A extends GenericClass<A> {
		  @Override
		  public void method() {
		  System.out.println("This is A::method()");
		  }

}

public class B extends GenericClass<B> {
		    @Override
		    public void method() {
		    System.out.println("This is B::method()");
		    }
}

public class Main {

			/**
			 * @param args
			 */
			public static void main(String[] args) {

			A a = new A();
			A a2 = new A();
			a.setValue(a2);
			a2.setValue(a);


			B b = new B();
			b.method();

			B b2 = b.hoge();
			b2.method();

			}

}