SlideShare a Scribd company logo
1 of 66
Download to read offline
ジェネリクスの基礎と
クラス設計への応用 2013 年版

Twetter : @nagise
はてな : Nagise
所属

  java-ja

 北陸エンジニアグループ
導入
Java 1.4 までのコード
ArrayList list = new ArrayList();
list.add("hoge");
String s = (String) list.get(0);
ジェネリクスのない世界
 Object 型からのダウンキャストが必要
 キャスト失敗は実行時例外
ClassCastException
 動かしてみないと間違いに気づかない
 ときに動かしても気づかない
 ドキュメントなどで型を明示
導入
Java 1.5 からのコード
ArrayList<String> list =
new ArrayList<String>();
list.add("hoge");
String s = list.get(0);
ジェネリクス以後の世界
 コレクション API でダウンキャストが不
要に
 コンパイル時点で型の間違いに気づく
 IDE によってはコンパイル前に気づく
 型システムが型を把握してくれる
 必修事項が増えました
今日のキーワード

Generics Hell
じぇねりくす へる
日本風に言えば「まったく Java のジェネリクスは地獄だぜ!」
略して「ヘル - い」などと表現したりする
入門編

 ジェネリックな API を利用するのに必要
な知識を身に着ける
 2種類のスコープ
 3種の山括弧
 代入について
ジェネリクスの2種類のスコー
プ
メソッドの中でのみ有効なジェネリクス
public static <T> void hoge(T t) { … }
インスタンスの中でのみ有効なジェネリク
ス
class Hoge<T> {
Tt;
...
}
ジェネリックメソッド

メソッドの引数と戻
り値の型の関係を表
す


メソッドの複数の引



数の型の関係を表す
ジェネリックメソッドの例
java.util.Collections クラス
リスト内に出現する指定された値を
すべてほかの値に置き換えます。
public static <T> boolean replaceAll
(List<T> list, T oldVal, T newVal)

3つの引数が List<T> 型、 T 型、 T 型という関係性
ジェネリックメソッドの例
java.util.Collections クラス
指定されたオブジェクトだけを格納している
不変のセットを返します
public static <T> Set<T> singleton(T o)
引数が T 型で、戻り値が Set<T> 型という関係性
ジェネリックメソッドの例
java.util.Collections クラス
デフォルトの乱数発生の元を使用して、
指定されたリストの順序を無作為に入れ替えます。
public static void shuffle(List<?> list)
引数1つだけなので関連性を示す必要がない。
無駄に型変数を定義せず、ワイルドカードを利用して
List<?> 型として宣言するほうが使い勝手が良い
ジェネリックメソッドの呼び出
し方
List<String> list = new ArrayList<String>();
list.add("hoge");
Collections.<String>replaceAll(list, "hoge", "piyo");
List<Integer> intList = new ArrayList<Integer>();
intList.add(42);
Collections.<Integer>replaceAll(intList, 42, 41);
static の場合はクラス名 .< バインド型 > メソッド名 (…)
インスタンスメソッドの場合は変数名 .< バインド型 > メソッド名
(…)
this に対するメソッド呼び出し時、明示的にバインドしたい場合は
this を省略できない
インスタンスの I/O
複数のメソッ
ド間の引数・戻
り値の型の関係
性


公開されてい



るフィールド
内部クラス


ジェネリックなインスタンスの
例
java.util.ArrayList の例
public boolean add(E e)
public E get(int index)
複数のメソッド間で型の関連性を表現している
ジェネリクスと構造化

ジェネリクスメソッド、ジェネリッククラスとも
に
ある囲いを作って、その内外のやりとりを
する場合のデータ型を型変数で抽象化する。
そのため、ジェネリックな設計をするためには
前提としてきれいな構造化をする必要がある。
文法のはなし
public class Syntax<T>
implements Iterable<String> {
public <X> void hoge(X x) {
List<X> list = new ArrayList<X>();
list.add(x);
}
@Override
public Iterator<String> iterator() {
return null;
}
}
似て非なる<>を色分けしてみました
3種類の<>
型変数の宣言
class Hoge<T> {}
public <T> void hoge() {}


型変数のバインド



new ArrayList<String>();
class Hoge extends ArrayList<String> {}
Collections.<String>replaceAll(
list, "hoge", "piyo");

パラメータ化された型
( parameterized type )
List<String> list;

型のバインド
ジェネリックメソッドの例
宣言側 仮型引数( type-parameter )
public static <T> boolean replaceAll
(List<T> list, T oldVal, T newVal)
利用側 実型引数( type-argument )
Collections.<String>replaceAll(
list, "hoge", "piyo");
型のバインド
ジェネリッククラスの例
宣言側 仮型引数( type-parameter )
public class ArrayList<E> {...}
利用側 実型引数( type-argument )
List<String> list = new ArrayList<String>();
( 参考 ) 仮引数と実引数
メソッドの仮引数と実引数との対比
宣言側 仮引数( parameter )
public void hoge(int index){...}
利用側 実引数( argument )
hoge(123);
型推論
ジェネリックメソッド
正書法
Collections.<String>replaceAll(
list, "hoge", "piyo");

型推論
Collections.replaceAll(
list, "hoge", "piyo");
ダイヤモンド演算子
ジェネリッククラス
正書法
List<String> list = new ArrayList<String>();

ダイヤモンド演算子
List<String> list = new ArrayList<>();
推論器
ジェネリックメソッドの型推論と
ダイヤモンド演算子は同じ機構を利用し
ている
Java7 では推論が弱いが、 Java8 ではラ
ムダのために
型推論が強化された
継承によるバインド
public class StringList
extends ArrayList<String> {}
というクラスを作ると
StringList list = new StringList();
list.add("hoge");
String str = list.get(0);
といったように、型変数のないクラスになる
複雑になる前に

Map<String, Map<Integer, List<Hoge>>>
みたいにジェネリクスが複雑化するようなら
適度なレベルでした継承クラスを作ることで
シンプルでわかりやすくなる
クラスを作るのをサボらない
サンプルのクラス
パラメータ化された型の代入互換
性
B[] arrayB = new B[1];
A[] arrayA = arrayB;
arrayA[0] = new B2();
→ ArrayStoreException が発生
List<B> listB = new ArrayList<B>();
List<A> listA = listB;
listA.add(new B2());
→ コンパイルエラー
異なる代入互換性
B の集合型 ArrayList<B> は
A の集合型 ArrayList<A> の
代理をできない
ワイルドカードの使用
ArrayList<? extends B> の範囲

ArrayList<? super B> の範囲
<? extends ~ > の入力制約
List<? extends B> には add() できない


List<C> 型を代入



B 型を add() とする



List<C> に B 型が add() される ←矛盾



get() は B 型の戻り値を返す
<? super ~ > の出力制約
ArrayList<? super B> には
B 型を add() できる



ただし get() は Object 型としてしか返せな
い

まとめ
型変数でメソッドやインスタンスの I/O の
型の関連性を表す
→ まずは綺麗なオブジェクト指向の設計を
文法をマスターするには
3種類の<>を意識する
代入互換性は訓練あるのみ
中級編
 ジェネリックな API を設計するのに必要
な知識を身に着ける
 型変数の宣言
 再帰的ジェネリクス
 内部クラス
 リフレクション
型変数の境界
class Hoge<T extends B>
型変数の宣言時には境界を指定できる
new Hoge<A>(); ←
new Hoge<B>(); ←
new Hoge<B2>(); ←
new Hoge<C>(); ←

NG
OK
NG
OK
型変数の境界

class Hoge <T extends A & Serializable>
& で繋いでインタフェースを
境界に加えることができる
再帰ジェネリクス

public abstract class
Hoge<T extends Hoge<T>> {
public abstract T getConcreteObject();
}
Hoge 型の型変数 T は Hoge 型を継承していなくてはなら
ない
再帰する型変数へのバインド

new でバインドできない
Hoge<?> hoge = new Hoge<Hoge<...>>();
再帰ジェネリクスは継承で扱う
public class Piyo extends Hoge<Piyo> {...}
再帰ジェネリクスの効能
public class Piyo extends Hoge<Piyo> {
@Override
public Piyo getConcreteObject() {
return this;
}
}
このようにすると
Piyo piyo = new Piyo();
Piyo piyo2 = piyo.getConcreteObject();
再帰ジェネリクスの効能

public abstract class
Hoge<T extends Hoge<T>> {
public abstract T getConcreteObject();
}
親クラスで定義されたメソッドなのに
子クラスの具象型を扱うことができる…!
再帰ジェネリクスの使用例
java.lang.Enum クラスの例
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable
{
public final int compareTo(E o) {…}
}
再帰ジェネリクスの使用例
enum SampleEnum {
ONE,
TWO,
}
に対して
SampleEnum.ONE.compareTo(SampleEnum.TWO);
は安全に compareTo できる。
他の enum と比較しようとするとコンパイルエラー
内部クラスのジェネリクス

内部クラスは外部クラスの型変数を利用できる
public class Outer<T> {
public class Inner {
T genericField;
}
}
内部クラスの new の仕方
内部クラスの new の仕方知ってますか?
Outer<String> outer = new Outer<String>();
Outer<String>.Inner inner = outer.new Inner();
内部クラスは外部クラスのインスタンスに紐づく。
ジェネリクスは「インスタンスの I/O で型の関連性を示
す」
の I/O には内部クラスも含まれます
内部クラスの利用例
public class SampleList<T> extends ArrayList<T> {
@Override
public Iterator<T> iterator() {
return super.iterator();
}
public class SampleIterator
implements Iterator<T> {
// 略
}
}
そもそも内部クラスの使いどころが難しいですが。
リフレクション
• 型変数に格納されるインスタンスの型情
報は欠落する(イレイジャ方式)
• メソッド引数やフィールド宣言に用いら
れるパラメタライズド・タイプの型情報
は欠落しない
http://d.hatena.ne.jp/Nagise/20121226/1356531878
Java のジェネリクスとリフレクション
リフレクション
java.lang.reflect.Type を利用
実装クラス / サブ interface
•Class – いつもの
•GenericArrayType – ジェネリックな配列。きも
い
•ParameterizedType – パラメタライズドタイプ
•TypeVariable<D> - 型変数
•WildcardType – ワイルドカード
ダウンキャストして使う
リフレクション
java.lang.reflect.Type を返すメソッドを利用する
•Class # getGenericSuperclass() : Type
•Class # getGenericInterfaces() : Type[]
•Method # getGenericParameterTypes() : Type[]
•Method # getGenericReturnType() : Type
•Field # getGenericType() : Type
などなど
まとめ
ジェネリクスが複雑になりすぎないように
継承でのバインドの利用を検討する
再帰ジェネリクスを応用すれば
サブクラスで具象型を扱える
内部クラスもスコープ範囲内
リフレクションでフィールドやメソッド引
数・戻り値のパラメタライズドタイプの型
をとれる
上級編

 ジェネリックな API の設計例
 利用側のコードとともによい設計を考え
る
new T() したい
動機
  DB のマッパーや Web システムの
Controller のようなフレームワークを作っ
た場合、
取り扱うオブジェクトの型をジェネリクス
で定義し、インスタンスを生成してデータ
をマッピングして渡したい
コンストラクタ
Java のオブジェクト指向の一般論おさらい
interface や親クラスとして
振る舞うことが要求される
具象型の特有の情報を
押し込める場所はコンストラクタ
コンストラクタ

コンストラクタの引数の形は継承で
制約できません
やりたければ Factory クラス作れ
一般にインスタンス生成は抽象化しにくい
Factory の実装例
interface HogeFactory<T extends A> {
/** デフォルトコンストラクタ的な */
T newInstance();
}
インスタンスの生成に必要なデータを Factory で制約
public class HogeTemplate {
public <T> T template(HogeFactory<T> factory)
{
return factory.newInstance();
}
}
こうすればインスタンスの生成は可能になる、が面倒
妥協例
public <T extends A> T template(T obj) {
try {
return (T)obj.getClass().newInstance();
} catch (InstantiationException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public <T extends A> T template(Class<T> clazz) {
try {
return (T)clazz.newInstance();
} catch (InstantiationException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
}
デフォルトコンストラクタがあることが前提
C# の例

class MyGenericClass<T> where T : new() {}
T 型にデフォルトコンストラクタがあることという制約。
デフォルトコンストラクタがあることを保証させることで
インスタンス生成を可能とする。
この制約はダサい制約ではあるが妥当な妥協点か。
Java でもリフレクションで生成する場合に
デフォルトコンストラクタがあることという制限をつけがち。
継承によるバインドの場合
Class # getGenericSuperclass() という福音
継承によるバインドであれば、型情報から型変数に何がバ
インドされたかを知ることができる
Type を ParameterizedType にキャスト
getActualTypeArguments() でバインドされた実体
実体の Type を Class にキャストして newInstance()
ただし、デフォルトコンストラクタがあるものとする
http://d.hatena.ne.jp/Nagise/20130815
ジェネリックなデザインパター
ン
Template Method パターン
虫食いのテンプレートを作る。
左図の処理 ABC は abstract メソッド。
サブクラスではオーバーライドして実装を書く。
ここに先の継承によるバインドと
バインドされた型のリフレクションでの
newInstance() を複合すると便利

処理 A
処理 B
処理 C
まとめ

New T() したくなるシチュエーションには
継承によるバインド+リフレクション
を使えないか検討する
Template nethod パターンと複合させると
フレームワークに応用できるかも
変態編

 何かに使えるかもしれない
再帰での相互参照
二つの型の具象型が、相互に相手の具象型を知っている
class Hoge<H extends Hoge<H, P>,
P extends Piyo<H, P>>
class Piyo<H extends Hoge<H, P>,
P extends Piyo<H, P>>
実装は
class HogeImpl extends Hoge<HogeImpl, PiyoImpl>
class PiyoImpl extends Piyo<HogeImpl, PiyoImpl>
相互再帰+1
汎用型変数 T を追加してみる
class Hoge<T, H extends Hoge<T, H, P>,
P extends Piyo<T, H, P>>
class Piyo<T, H extends Hoge<T, H, P>,
P extends Piyo<T, H, P>>
実装クラス
class HogeImpl<T> extends
Hoge<T, HogeImpl<T>, PiyoImpl<T>>
class PiyoImpl<T> extends
Piyo<T, HogeImpl<T>, PiyoImpl<T>>
やりすぎです
内部クラスでグルーピング
二つのクラスを囲うクラスを作って
Hoge と Piyo を内部クラスにすれば…!
public abstract class Outer
<H extends Outer<H, P>.Hoge,
P extends Outer<H, P>.Piyo> {
public abstract class Hoge {
public abstract P getConcretePiyo();
}
public abstract class Piyo {
public abstract H getConcreteHoge();
}
}
やりすぎです
型変数の部分適用
複数の型変数がある型を2段階に分けてバインド

public class Outer<K> {
public class Inner<V> extends HashMap<K, V> {}
}
Outer<String> o = new Outer<String> ();
HashMap<String, Integer> inner =
o. new Inner<Integer>();
応用例

型変数の部分適用

http://d.hatena.ne.jp/Nagise/20110124/1295874192
Java による高階型変数の実装
public class Hoge extends KeyGroup<Hoge> {
private static final Hoge singleton = new Hoge();
public static final Hoge.Key<String>
HOGE_STRING = singleton.new Key<String>();
}
public class KeyValue<KG extends KeyGroup<KG>> {
public <T> void put(KeyGroup<KG>.Key<T> key, T value){}
}
KeyValue<Hoge> tm = new KeyValue<Hoge>();
tm.put(Hoge.HOGE_STRING, "hoge");
より深く知りたい場合の資料
当セッションは主に blog に記述した事項を再編集
してまとめたものである。
Blog プログラマーの脳みそ
カテゴリー Generics を参照
http://d.hatena.ne.jp/Nagise/searchdiary?word=
%2A%5BGenerics%5D
Generics Hell に遭遇したら Twitter で
@nagise にご一報ください。

More Related Content

What's hot

DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
20190514 AWS Black Belt Online Seminar Amazon API Gateway
20190514 AWS Black Belt Online Seminar Amazon API Gateway 20190514 AWS Black Belt Online Seminar Amazon API Gateway
20190514 AWS Black Belt Online Seminar Amazon API Gateway Amazon Web Services Japan
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
はじめての datadog
はじめての datadogはじめての datadog
はじめての datadogNaoya Nakazawa
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティスAmazon Web Services Japan
 
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤Amazon Web Services Japan
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAkihiro Kuwano
 
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Yahoo!デベロッパーネットワーク
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方Recruit Lifestyle Co., Ltd.
 
DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化DeNA
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション土岐 孝平
 
Azure API Management 俺的マニュアル
Azure API Management 俺的マニュアルAzure API Management 俺的マニュアル
Azure API Management 俺的マニュアル貴志 上坂
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDayマイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay都元ダイスケ Miyamoto
 
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)NTT DATA Technology & Innovation
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 

What's hot (20)

Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
20190514 AWS Black Belt Online Seminar Amazon API Gateway
20190514 AWS Black Belt Online Seminar Amazon API Gateway 20190514 AWS Black Belt Online Seminar Amazon API Gateway
20190514 AWS Black Belt Online Seminar Amazon API Gateway
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
はじめての datadog
はじめての datadogはじめての datadog
はじめての datadog
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
 
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
 
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
Azure API Management 俺的マニュアル
Azure API Management 俺的マニュアルAzure API Management 俺的マニュアル
Azure API Management 俺的マニュアル
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDayマイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
 
Guide To AGPL
Guide To AGPLGuide To AGPL
Guide To AGPL
 
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
20211109 JAWS-UG SRE keynotes
20211109 JAWS-UG SRE keynotes20211109 JAWS-UG SRE keynotes
20211109 JAWS-UG SRE keynotes
 

Similar to ジェネリクスの基礎と クラス設計への応用

Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010stomita
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門kamukiriri
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?Kenji Nakamura
 
夏だからJava再入門
夏だからJava再入門夏だからJava再入門
夏だからJava再入門Katsumi Honda
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2Masatoshi Tada
 
Scala EE 7 Essentials
Scala EE 7 EssentialsScala EE 7 Essentials
Scala EE 7 Essentialstnoda
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravelRisa Ohnishi
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkVSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkAtsushi Fukui
 
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallnagise
 
Spring mvc
Spring mvcSpring mvc
Spring mvcRyo Asai
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
TypeScript0.9
TypeScript0.9TypeScript0.9
TypeScript0.9ukayare
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングkunihikokaneko1
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 

Similar to ジェネリクスの基礎と クラス設計への応用 (20)

Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010
 
APIKit
APIKitAPIKit
APIKit
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?
 
夏だからJava再入門
夏だからJava再入門夏だからJava再入門
夏だからJava再入門
 
Rpscala2011 0601
Rpscala2011 0601Rpscala2011 0601
Rpscala2011 0601
 
Project lambda
Project lambdaProject lambda
Project lambda
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
 
Scala EE 7 Essentials
Scala EE 7 EssentialsScala EE 7 Essentials
Scala EE 7 Essentials
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravel
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkVSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
 
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
IgChart 入門編
IgChart 入門編IgChart 入門編
IgChart 入門編
 
TypeScript0.9
TypeScript0.9TypeScript0.9
TypeScript0.9
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 

ジェネリクスの基礎と クラス設計への応用