連載
Javaオブジェクトモデリング
第3回
静的モデル:クラスにおけるUMLとJavaのマッピング(1)
3.Javaの“クラス” |
■■3.1 クラス■■
Javaのクラスは前回ご紹介したとおり、図13のような形になります。この構造をモデル化したJavaクラスのメタモデルは図14となります。
図13 Javaのクラス |
図14 Javaのクラス メタモデル(クリックすると拡大します) |
- 1つのパッケージに属していることがある
- 1つの親クラスをextendsしていることがある
- 0個以上複数個のインターフェイスをimplementsしている
- 1つの可視性を持っている
- abstractが指定されていることがある
- finalが指定されていることがある
- 1つのクラス名を持っている
- 0個以上複数個のメソッドを持っている
- 0個以上複数個のクラスメソッドを持っている
- 0個以上複数個のコンストラクタを持っている
- 0個以上複数個の定数を持っている
- 0個以上複数個のインスタンス変数を持っている
- 0個以上複数個のクラス変数を持っている
Javaでは以下のクラスを言語仕様上特別扱いしています。
- 配列
- java.lang.Object
- java.lang.Class
- java.lang.Throwable
- java.lang.Error
- java.lang.Exception
- java.lang.RuntimeException
- java.lang.String
- java.lang.Thread
- java.lang.Objectは、すべてのJavaオブジェクトのルートオブジェクトです。extendsによって親クラスを指定しない場合、暗黙的にこのオブジェクトが継承されることになります。
- java.lang.Classは、クラスを表現するためのクラスであり、いわゆるメタクラスと呼ばれるものです
- java.lang.Throwableは、Java言語においてエラーや例外を表すクラスです。メソッド定義でthrows句に記述できるのは、このThrowableのサブク
ラスのみとなっています。Javaの実行系(Java VM)およびJavaプログラムはThrowableまたはThrowableのサブクラスをthrowすることで、通常のプ
ログラム制御シーケンスとは異なる、異常処理用の制御シーケンスを引き起こすことができます
- java.lang.Errorは、java.lang.Throwableのサブクラスであり、Java言語においてエラーを示すクラスです
- java.lang.Exceptionはjava.lang.Throwableのサブクラスであり、Java言語において例外を示すクラスです。Exceptionのサブクラス(かつRuntimeExceptionのサブクラスでない)は、いわゆる検査例外と呼ばれており、throwするためにはメソッドのthrows句で指定する必要があります
- java.lang.RuntimeExceptionはExceptionのサブクラスであり、throws句に指定する必要のない、いわゆる検査なしの例外を表すクラスです
- java.lang.Stringは、Java言語で文字列を実現するクラスです。java.lang.Stringは、言語仕様上特別な意識がされており、あたかもプリミティブ型のような使い勝手となっています
- java.lang.Threadは、Java言語でスレッド機能を実現するクラスです
Javaのインターフェイスは前回ご紹介したとおり、図15、16のような形になります。
図15 Javaのインターフェイス |
図16 Javaのインターフェイス メタモデル |
- 1つのパッケージに属していることがある
- 0個以上複数個のインターフェイスをextendsしている
- 1つの可視性を持っている
- strictfpが指定されていることがある
- 1つのインターフェイス名を持っている
- 0個以上複数個のメソッドを持っている
- 0個以上複数個の定数を持っている
UMLのインターフェイスは「オペレーションの集まり」を表すものですから、定数の宣言を行うことができるJavaのインターフェイスは厳密な意味では違うものと考えることもできます。また、そもそもUMLには定数という概念はないので、「定数は属性の一種である」という仮説を持ち込まなければ、純粋にJava独自の言語機能と考えることもでき、「UMLのインターフェイス=Javaのインターフェイス」という定義は意味論上も矛盾しないと考えることもできます。いずれにしても、実用上はこのような細かな違いを厳密に扱うよりも、「Javaのインターフェイス=UMLのインターフェイス」と扱うことの方がはるかにメリットが多いことはいうまでもありませんし、本連載でもそのように扱っていきます。
■■3.4 インターフェイスの種類■■
Javaでは以下のインターフェイスを言語仕様上特別扱いしています。
- java.lang.Cloneable
- java.lang.Runnable
- java.io.Serializable
- java.io.Externalizable
- java.lang.Cloneableは、クローン可能なオブジェクトであることを示すインターフェイスです。java.lang.Cloneableをimplementsしたオブジェクトは、cloneメソッドでオブジェクトの複製ができるようになります。
- java.lang.Runnableは、スレッドを割り当てることができるオブジェクトであることを示すインターフェイスです。java.lang.Runnableをimplementsした
オブジェクトは、java.lang.Threadのコンストラクタに指定することで、新たに生成されたスレッド上で動作します。
- java.io.Serializableは、直列化可能なオブジェクトであることを示すインターフェイスです。java.io.Serializableをimplementsしたオブジェクトは、java.io.ObjectOutputStreamおよびjava.io.ObjectInputStreamを用いて直列化を行うことができるようになります。
- java.io.Externalizableは、java.io.Serializableのサブインターフェイスであり、直列化可能なオブジェクトであることを示します。java.io.Serializableとの相違点は、直列化の制御をどの程度行うことができるかという点にあります。java.io.Serializableは、直列化の制御は
Java実行系が完全に行ってくれて、必要に応じて制御の一部をユーザーオブジェクト側で行えるようになっています。それに対して java.io.Externalizableは、直列化の制御のコードを必ずユーザーオブジェクト側で用意しなければなりませんが、直列化の制御を完全にユーザーオブジェクト側で行うことができるようになっています。
■■3.5
メソッド■■
Javaメソッドのメタモデルは図17となります。
図17 Javaのメソッド メタモデル(クリックすると拡大します) |
- 可視性を1つ持っている
- staticの指定が行われていることがある
- finalの指定が行われていることがある
- abstractの指定が行われていることがある
- nativeの指定が行われていることがある
- synchronizedの指定が行われていることがある
- strictfpの指定が行われていることがある
- 復帰型を1つ持っている
- メソッド名を1つ持っている
- 0個以上複数個のパラメタを持っている
- 0個以上複数個の例外を持っている
図18 Javaのメソッドの文法 |
可視性は、public、protected、privateおよび表記の省略の4つの指定方法が用意されています。publicが公開、protectedが子孫クラスに公開、privateが公開しない、省略がパッケージ内に公開となっています。
メソッドの性質を示す修飾子としてstatic、final、abstractが用意されています。staticが指定されるとクラススコープのメソッドとなります。finalは子孫クラスによるメソッドのオーバーライドを許さないという指定、abstractは抽象メソッドの指定です。
メソッドの実装を示す修飾子としてnative、synchronized、strictfpが用意されています。
図17に示すとおり、staticとabstractの修飾子の指定によって、Javaでは3種類のメソッドを定義することができます。まず、1番上にあるのが通常のメソッドです。2番目にあるのが抽象メソッドです。抽象メソッドはメソッドのシグネチャの定義のみを行い実装は定義しません。3番目にあるのがクラスメソッドです。また、通常のメソッドは修飾子finalによって、子孫クラスでオーバーライドできないように指定することができます。
復帰値は必ず指定する必要があります。復帰値として値を返す必要がない場合はvoidを指定します。Javaでは、メソッドのシグネチャにメソッドが送出する可能性のある例外を定義することができます。
■■3.6 コンストラクタ■■
コンストラクタのメタモデルは図19となります。
図19 Javaのコンストラクタ メタモデル |
- 可視性を1つ持っている
- メソッド名を1つ持っている
- 0個以上複数個のパラメタを持っている
- 0個以上複数個の例外を持っている
■■3.7 属性■■
JavaではUMLの属性に相当する機能として変数が用意されています。しかし、変数には多くの種類があり、その一部がUMLの属性に対応する形になっています。
●3.7.1 用途による分類
Javaの変数は用途によって図20の(1)に示す以下の種類に分類することができます。
- インスタンス変数
- クラス変数
- ローカル変数
- コンストラクタパラメタ
- メソッドパラメタ
- 例外ハンドリングパラメタ
図20 Java変数の種類 |
●3.7.2 格納方法による分類
Javaの変数は格納する情報によって図20の(2)に示す種類に分類することができます。
- プリミティブ型
- 参照型
- 配列に対する参照型
Javaにおける配列は、配列オブジェクトによって実現されています。このため実行モデル上は配列オブジェクトに対する参照型の変数として実現されています。ただし、文法上はC言語の配列のように利用できるように考慮されているため、配列は通常の参照型の変数とは分けて考えます。
例えばJavaの変数のモデルは図21に示すようになります。この図ではオブジェクト内に3つの変数が定義されています。 変数balanceはプリミティブ型の変数、変数personは一般的なオブジェクトに対する参照型の変数、変数personsは、配列オブジェクトに対する参照型の変数となっています。
図21 Java変数のモデル |
●3.7.3 属性に相当する変数
UMLの属性に相当するJavaの変数はインスタンス変数とクラス変数になります。ここでは、インスタンス変数とクラス変数を総称して属性と呼ぶことにします。Java属性のメタモデルは図22となります。
図22 Java属性メタモデル |
- 可視性を1つ持っている
- staticの指定が行われていることがある
- finalの指定が行われていることがある
- volatileの指定が行われていることがある
- transientの指定が行われていることがある
- 型を1つ持っている
- 属性名を1つ持っている
- 初期値を持っていることがある
図23 Java属性の文法 |
可視性は、public、protected、privateおよび表記の省略という4つの指定方法が用意されています。publicが公開、protectedが子孫クラスに公開、privateが公開しない、省略がパッケージ内に公開となっています。
属性の性質を示す修飾子としてstatic、finalが用意されています。staticが指定されるとクラススコープの属性となります。finalは初期化あるいはコンストラクタ以外で値の設定を許さない属性の指定です。staticとfinalを同時に指定することもできますが、この場合は意味が変わり、定数の指定となり ます。
volatileとtransientは、属性に対する操作に関する修飾子です。
volatileは、複数のスレッドから同時にアクセスされた場合に矛盾を起こさない変数であることを示します。通常はvolatileの指定は外れているので、複数のスレッドから同時にアクセスした場合に内容に矛盾が生じても構わないことになります。
transientは、java.io.ObjectOutputStreamを使ってオブジェクトを直列化する場合に、直列化対象の変数ではないことを示します。通常はtransientの指定は外れているので、オブジェクトの直列化の際には直列化対象となりますが、直列化対象でありながらjava.io.Serializableでないオブジェクトがあった場合には例外が発生します。
4/4
|
Javaオブジェクトモデリング 第3回 | |
分類子と“クラス” | |
UMLの“クラス”(1) | |
UMLの“クラス”(2) | |
Javaの“クラス” |
筆者プロフィール |
浅海智晴(あさみ ともはる) 著書に「Java Super Tips オブジェクト指向設計編」、「XML/DOM Programming」(秀和システム)、 |
Javaオブジェクトモデリング INDEX |
IT Architect 連載記事一覧 |
アーキテクチャ 新着記事
@IT情報マネジメント 新着記事
この記事に対するご意見をお寄せください managemail@atmarkit.co.jp