*

Java超入門 with Eclipse[4:クラスに関する基礎知識(修飾子とクラスとインスタンスと変数)]

公開日: : 最終更新日:2015/05/02 Eclipse, Java


スポンサードリンク



前回は、Javaの基本であるクラスの基本的な知識をざっくりと説明させていただいたあと、
package(パッケージ)の詳細な説明をさせていただきました。

今回は前回説明できていない、修飾子を説明させていただいたあと、
クラスとインスタンスと変数の詳細な説明をさせていただきます。

次回、第五回はメソッドの説明
第六回はインターフェースと継承を説明させていただきます。

本エントリーの内容は以下の通りとなります。

  1. 修飾子の説明
  2. クラスとインスタンスと変数の詳細な説明

 

1 修飾子の説明

Javaで指定可能な修飾子の一覧

利用可能な修飾子は以下のようになります。

修飾子 種別 説明
public アクセス修飾子 全てのクラスで参照可能になる。
protected アクセス修飾子 自クラスとその継承クラスで参照可能になる。
private アクセス修飾子 自クラスでのみ参照可能になる。
abstract 抽象修飾子 実体(実装)を持たないクラス、メソッドになる。
static スタティック修飾子 クラス(静的)メンバになる。
final ファイナル修飾子 上書き不可になる。
const 定数修飾子 定数になる。
transient 一時的修飾子 シリアライズ対象外となる。
volatile 揮発性修飾子 マルチスレッド時の値の整合性を保証する。
synchronized 同期修飾子 スレッドセーフな処理になる。
native ネイティブ修飾子 C言語等で実実装を行う場合に指定する。
strictfp 厳密浮動小数修飾子 浮動小数点演算がプラットフォームに依存しない厳密な動作をする。

 

アクセス修飾子

修飾子で最もよく利用されるのが「アクセス修飾子」です。
「アクセス修飾子」は「クラス」と「クラスの保持する変数、メソッド」に付与され、
付与対象がどのようなクラスから参照可能であるかを制御します。

先ほどの修飾子一覧には記載されていませが、「アクセス修飾子」として「デフォルト修飾子」が存在します。
「アクセス修飾子」を明示的に付与しない場合は、「デフォルト修飾子」が付与されたと見なされます。

以下の表が、付与されたアクセス修飾子と、参照可能なクラスの関係をあらわした物となります。
可が参照可能、不可が参照不可を意味しています。

同一パッケージは同一パッケージに含まれるクラス、その他はその他のクラスを意味しています。

サブクラスですが、まだクラスにおける継承を説明できておりませんので意味不明であると思いますが、
クラスには継承と言う概念があり、現実世界を例に例えると、
「動物」クラスのサブクラスが「哺乳類」クラスや「魚類」クラスとなります。継承につきましては「第六回」で説明させていただきます。

アクセス修飾子 自クラス サブクラス 同一パッケージ その他 備考
public 全てのクラスで参照可能
protected 不可 クラスに対しては付与できない
private 不可 不可 不可 自クラスだけで参照可能
デフォルト 不可 不可 アクセス修飾子が付与されていない時

 

各修飾子のもう少し細かな説明を以降でさせていただきます。

スタティック修飾子

スタティック修飾子は、定数、変数、メソッドに付与可能です。クラスの宣言時には付与できません。

スタティック修飾子を付与するとクラス(静的)メンバになります。
メンバとは定数、変数、メソッド等のクラスの中身を意味します。

クラスメンバとは、インスタンスではなく、クラスに属するメンバです。
インスタンスに属するメンバはインスタンスメンバとよばれています。

「第三回」で説明に利用した
「たい焼き」クラスのたい焼きを「焼く型」に属するメンバがクラスメンバで、
「焼き上がったたい焼き」に属するメンバがインスタンスメンバとなります。

コードを利用した実際の利用方法は後述いたします。

ファイナル修飾子

クラス、変数、メソッドに付与可能です。付与されると上書きが禁止となります。
以下の場合にファイナル修飾子が利用されます。

  • サブクラスの作成を禁止したいクラス
  • 値の変更を禁止したい変数
  • オーバーライドを禁止したいメソッド

オーバーライドとはサブクラスで基底クラスのメソッドの動作を上書きすることです。
「たい焼き」クラスにはvoid swim()とのメソッドが存在しており、
「たい焼き」クラスを継承して、「たい焼き君」クラスを作成したとします。

この時、「たい焼き君」クラスでもvoid swim()を作成するとします。
この行為がswimメソッドのオーバーライドです。
やや強引ですが・・・、オーバーライドは第六回で説明させていただきます。

定数修飾子

見ての通りです。変更が不可な定数になります。
変数にしか付与できません。といっても付与した時点で変数ではなくなります。

抽象修飾子

クラス、インターフェース、メソッドに付与できます。
宣言にabstractを付与することで、宣言された物が不完全であることを意味します。

抽象修飾子が付与されたクラスを抽象クラス、メソッドを抽象メソッドと呼びます。

また出ました、今度はインターフェースですか、まだ説明できておりませんね。
でも心配ありません。インターフェースは元々不完全な物ですので、付与はできるけど、
そんな事をしても意味ないです。abstractなインターフェースを作成するのは言語仕様としても非推奨となっています。
インターフェースの詳細は、第六回で説明させていただきます。

話は元に戻って、何をもって不完全?、と思われるのが自然ですね。
抽象修飾子が付与されると、そのクラスのインスタンスを作成しようとするとコンパイルエラーとなります。

なお、抽象メソッドをメンバに持つクラスは、必ず抽象クラスである必要があります。
こちらもコンパイルエラーとなります。

ネイティブ修飾子

実際の処理はC言語等で実装を行う場合に指定する修飾子です。
Java側には呼び出しのインターフェース(実装は無いメソッド定義)を記載するだけです。

私Javaを使い始めて15年ぐらいになりますが、かなり前に1回だけ使った記憶があります。

同期修飾子

メソッドに付与される修飾子です。マルチスレッド環境で実行される場合は、
メソッドが属するインスタンスを対象として排他制御が行われます。
よって、同一インスタンスの同期修飾子付きのメソッドが同時に複数実行される場合のみスレッドセーフとなります。

逆に、複数インスタンスの同期修飾子付きのメソッドが同時に複数実行される場合はスレッドセースにはなりません。

同期処理については、別エントリーで説明させていただこうと考えております。

一時的修飾子

Javaにはシリアライズ、デシリアライズという機構が存在しています。
この機構は、「Java VM」上に存在するインスタンスをファイルシステム上のファイルに出力したり、その逆の処理を可能にします。

SOAPやEJB等も、インスタンスを複数サーバ間でやりとりするためにシリアライズ、デシリアライズを利用しています。
Javaはデフォルトでオブジェクトのすべてのメンバをシリアライズの対象としますが、一時的修飾子が付与された変数は対象外となります。

揮発性修飾子

Javaの各スレッドは速度向上等のために、変数を自身のメモリー空間にコピーして利用し、
スレッドの処理が終わった時点で元の変数に自身のメモリー空間の値を書き戻します。

複数のスレッドから参照される可能性のある変数にvolatileをつけることにより、各スレッドがこの変数を直接参照、更新するようになります。

厳密浮動小数修飾子

strictfp修飾子をクラス、インターフェース、メソッドに付与すると、浮動小数点の演算がプラットフォームに依存しない厳密な動作をするようになります。

strictfpを付与しない場合の浮動小数点の演算は、プラットフォームに依存し、値が若干異なる場合があります。

複数の修飾子を付与するときの記載順序

「Checkstyle 日本語訳 バージョン 4.1」の「ModifierOrder」
によると以下の順番が正しい記載順序です。

  1. public
  2. protected
  3. private
  4. abstract
  5. static
  6. final
  7. transient
  8. volatile
  9. synchronized
  10. native
  11. strictfp

 

2 クラスとインスタンスと変数とメソッドの詳細な説明

第三回の終了時点のコードを確認

説明に入る前に、第三回の終了時点のコードを確認しておきます。

TaiyakiCreator.java

Taiyaki.java

この例では、TaiyakiクラスをTaiyakiCreatorから利用するようになっています。
現状ではTaiyakiのアクセス修飾子は「public」ですのでTaiyakiCreatorから参照可能です。

修飾子とクラス

クラスに付与可能な修飾子は以下の通りです。

  • アクセス修飾子
  • スタティック修飾子
  • ファイナル修飾子
  • 抽象修飾子
  • 厳密浮動小数修飾子

厳密浮動小数修飾子はこれ以上説明する事がございませんので省略します。

アクセス修飾子とクラス

これについては、追加の説明は不要かと思いますが、1問だけクイズを出させてください。
前述の例のTaiyakiのアクセス修飾子はpublicです。このpublicを他のアクセス修飾子に変更しても
TaiyakiCreatorから参照可能になる物は存在するか?

答えは、存在しないです。TaiyakiとTaiyakiCreatorが同一パッケージであれば他の選択肢もありますが、
異なる場合はpublicのみ参照可能です。

ファイナル修飾子とクラス

Taiyakiにfinal修飾子を付与してみましたが、何も起こりませんでした
final修飾子を付与することで、サブクラスが作成できないクラスになった。ただそれだけです。

抽象修飾子とクラス

Taiyakiのfinal修飾子はそのままにして、abstract修飾子も付与してみました。

するとコンパイルエラーが発生しました。
まあ予想通りですね、上書き禁止と、抽象(不完全)を両方宣言するということは、
不完全なままのクラスの継承を禁止しろとの意図になるのですから、意味不明ですよね。
スクリーンショット 2014-05-14 15.12.48

では、final修飾子を除去してみました。

Taiyakiは純粋にabstractになりましたので、当然インスタンスが作成できないはずです。
Eclipseでも予想通りのエラーが発生しました。
スクリーンショット 2014-05-14 15.17.57

クラスとインスタンス

第三回では、クラスとインスタンスの関係は説明させていただきましたし、
一番シンプルなクラスのインスタンス作成方法も説明させていただきました。

前回提示した、たい焼きクラスのインスタンスを作成する例

Taiyaki.javaでは、以下の部分が対応します。

このシンプルな例が実際には、どのように動作しているのかを説明し、
シンプルではないクラスのインスタンス作成例を説明したいと思います。

コンストラクタ

・デフォルトコンストラクタ
newの次に続いているTaiyaki()はデフォルトコンストラクタと呼ばれる物で、
引数無しのコンストラクタがデフォルトコンストラクタです。
.javaを作成した時点でデフォルトコンストラクタは利用可能です。

復習となりますが、現在のTaiyaki.javaは以下のようになっています。

見ていただいている通り、Taiyakiの中身は空っぽです。にも関わらずデフォルトコンストラクタは利用可能となります。

なお、デフォルト以外のコンストラクタが定義された場合は、
デフォルトコンストラクタを明示的に定義しなければ、デフォルトコンストラクタは利用不可能になります。この例は後ほど説明いたします。

・デフォルトコンストラクタ以外のコンストラクタ
コンストラクタの構文は以下の通りです。

アクセス修飾子 クラス名(仮引数1の型 仮引数1の名前, 仮引数2の型 仮引数2の名前) {
初期化処理
}

上記例では引数が2つとなっていますが、必要な分だけ増やしたり、減らしたりすることが可能です。

引数にintを1つ指定可能なコンストラクタをTaiyakiに追加してみました。

するとEclipseでコンパイルエラーが発生するようになりました。
スクリーンショット 2014-05-14 18.18.29

先ほど説明させていただいた、デフォルト以外のコンストラクタが定義されたので、デフォルトコンストラクタが利用不可能になったからです。

では、Eclipseのエラー修正機能を用いてデフォルトコンストラクタを追加します。

以下の画像の赤枠の部分をクリックします。
スクリーンショット 2014-05-14 18.27.13

以下のように画面表示が変化しますので、
「コンストラクター Taiyaki()の作成」を上下ボタンの下を1回押して選択状態にした後、「リターン」キーを押して修正を確定します。
スクリーンショット 2014-05-14 18.28.25

Taiyakiクラスにデフォルトコンストラクタが作成された状態で、画面は以下のように表示されますので、
パッケージを選択したらデフォルトコンストラクタの作成が完了です。
スクリーンショット 2014-05-14 18.34.01

デフォルトコンストラクタ追加後のTaiyaki

// TODOコメントの下にコメントで記載していますが、
基本的には、コンストラクタは基底クラスのコンストラクタを呼び出す必要があります。
詳細は第六回で説明させていただきます。

クラスとインスタンスと変数と定数

いよいよ変数です。以前から何回か「変数は箱です。」みたいな表現を使っていますが、
まさに箱ですが、変数にはメンバ変数(クラス変数やインスタンス変数)とローカル変数の2つが存在します。
クラス変数とインスタンス変数の違いについては後述いたします。

メンバ変数で注目すべきは、変数の型と修飾子です。
ローカル変数は、メソッドやブロック内で宣言され、その範囲でのみ利用可能な変数です。

なお、const修飾子が付与された変数が定数となります。

ローカル変数

ローカル変数にも付与可能な修飾子がありますが、利用する機会はほぼ無いに等しいですので説明は省略いたします。

宣言方法を以降で説明いたします。

初期値を指定しない場合

変数の型 変数の名前;

同じ変数の型の複数の変数を1行で宣言する場合は
変数の型 変数の名前1,変数の名前2;
のようにカンマで区切って一括して宣言できます。

初期値を指定する場合

初期値を指定する場合は変数名の後に=初期値;を追加します。
変数の型 変数の名前 = 初期値;

メンバ変数

メンバ変数に付与可能な修飾子

  • アクセス修飾子
  • スタティック修飾子
  • ファイナル修飾子
  • 一時的修飾子
  • 揮発性修飾子

修飾子については、既に説明が終わっていますので、特段記載する内容はありませんが
static修飾子が付与されている変数をクラス変数、
static修飾子が付与されていない変数をインスタンス変数と呼びます。

宣言方法

宣言方法を以降で説明いたします。

・初期値を指定しない場合
修飾子 変数の型 変数の名前;

同じ変数の型の複数の変数を1行で宣言する場合は
修飾子 変数の型 変数の名前1,変数の名前2;
のようにカンマで区切って一括して宣言できます。

・初期値を指定する場合
修飾子 変数の型 変数の名前 = 初期値;。

変数の宣言のよくあるパターン

「変数の宣言方法」では、修飾子の一言でかたづけましたが、変数宣言のキモは修飾子ですので
修飾子の組み合わせを含んだ変数宣言をTaiyakiに追加しました。
finalとprotectedを含んだ例も入れたいのですが、継承の説明後に説明することが効果的ですので、第六回で説明させていただきます。

Taiyakiは以下のようになりました。

・name1
name1(最悪なネーミングですね・・・)の注目ポイントは何もありません。

メンバ変数にはクラス変数かインスタンス変数しかありませんが、
name1はstatic修飾子が付与されていないのでインスタンス変数です。

実際にTaiyakiCreatorからname1変数を参照してみます。
参照方法は当然、インスタンス名.name1となります。

・name2
name2の注目ポイントはstatic修飾子です。
これが付与されることにより、name2はクラス(静的)変数となります。
クラス変数には、クラス名.変数名でアクセスします。

実際にTaiyakiCreatorからname2変数を参照しみようと思うのですが、
とりあえずインスタンス変数と同じ参照方法を記載してみます。

すると、「static フィールド Taiyaki.name2 には static にアクセスする必要があります」
との警告が表示されるようになりました。JDKの古いバージョンではコンパイルエラーになっていたと記憶しているのですが・・・
どこかのバージョンから警告に変わった様です。

確かに、インスタンスに対応するクラスをコンパイラは理解しているのだから、
クラス変数にインスタンス経由でアクセスしても、良きに計らってくれるのでしょう。

name2へstaticにアクセスするように変更してみます。
先ほどの警告は出力されなくなりました。

・name3
transient修飾子付与されたpublicな変数です。transientを付与したかった。ただそれだけです。

・name4
デフォルト修飾子とvolatileが付与された変数です。
volatileによって違いが出るサンプルは今回は実装しませんが、機会があれば別エントリーで取り上げたいと思います。

デフォルト修飾子は、自クラスと同一パッケージのクラスから参照可能です。
同一パッケージのクラスの方の確認は、任意のクラスを作成し、パッケージ名をhoge.fooにするだけですので、説明は省略させていただきます。

自クラスからの参照につきましては、private修飾子と同様ですので、name5で説明いたします。

・name5
private修飾子が付与されていますので自クラス(Taiyakiの内部から)しかアクセスできません。

自クラスからの参照を実装してみます。
デフォルトコンストラクタからname4の値を100.100に変更してみます。

この記載方法でも今の状態であれば問題ないのですが、問題が発生する可能性を考慮して、
その回避策が言語仕様に存在しています。

Taiyakiに以下のメソッドを追加しました。

int型のname5という名前のローカル変数を値10で宣言し、System.out.printlnでname5の値をコンソールに出力しています。

ここでクイズです。
・このswimメソッドでインスタンスメンバのname5にアクセスするにはどうしたらよいか?
・System.out.printlnで出力しているname5は本当にローカル変数のname5なのか?

1つ目のクイズの答えは、this.name5と記述することでアクセスできる。
2つ目のクイズの答えは、同じ名前のメンバ変数、ローカル変数が存在する場合は、ローカル変数が優先される。
となります。

以下のように記述すれば両方の変数にアクセスできますが、「あれー、this付け忘れちゃったよ」なんてことになると
バグを作り込んでしまう可能性が高くなるので要注意です。

Java超入門[4:クラスに関する基礎知識(修飾子とクラスとインスタンスと変数)]は以上です。


スポンサードリンク



関連記事

java8(JDK8)の新機能のラムダ式の利用方法をEclipseとJUnitで説明[その2:関数型インターフェースを例としたラムダ式]

「JDK8(Java 8)の新機能のラムダ式の利用方法」では、 指定できる場所の概説と関数型インタ

記事を読む

「HyperSQL」の環境を作成し、Eclipseの「DBViewer」プラグインを利用してSQLを発行してみる

Eclipseの「DBViewer」プラグインを利用して「Java DB」の環境を作成し、SQLを発

記事を読む

Selenium入門その3[Selenium WebDriver(Java/Junit4)の使い方]

WebDriverでは、予め中継サーバを起動しなくても、テスト実行時にブラウザ拡張機能や、OSのネイ

記事を読む

Eclipseの使い方(Windows環境のEclipse4.3、Eclipse4.4)

Eclipse4.4.0よりJDK8を正式サポートするそうです。 Eclipseトップレベルプ

記事を読む

Eclipse4.4(Java)におけるビルド・パス関係の設定方法[ビルド・パス上のソース・フォルダー]

Eclipse4.4(Java)におけるビルド関係のビルド・パス上のソース・フォルダーの利用方法を説

記事を読む

Eclipse(4.3,4.4)のJava言語のリファクタリング機能の使い方[リファクタリングの説明と「名前変更」と「移動」]

本エントリーでは、Eclipse(4.3,4.4)の「リファクタリング」機能の使い方を説明させていた

記事を読む

Selenium入門その5[ページオブジェクトパターン(Page Object Design Pattern)を利用して変更に強いテストを作成する方法]

Selenium入門その2 では「UIマップファイル」と言う仕組みが存在していることに言及させてい

記事を読む

Java超入門 with Eclipse[5:クラスに関する基礎知識(メソッドをJUnitを使って説明)]

クラスに関する基礎知識シリーズも、いよいよメソッドを残すのみとなりました。 前回までは、Eclip

記事を読む

Eclipse4.4(Java)におけるビルド・パス関係の設定方法[ビルド・パス上に必要なプロジェクト/プロジェクト参照の追加]

Eclipse4.4(Java)におけるビルド関係のビルド・パス上の「ビルド・パス上に必要なプロジェ

記事を読む

Eclipseの「DBViewer」プラグインの使い方[前編]

「HyperSQL」の環境を作成し、Eclipseの「DBViewer」プラグインを利用してSQLを

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Spring5入門[簡単なWebアプリのユニットテストをJUnit5とJMockitで作成]

Spring5入門ではJUnit4とmockitを利用したSpring

Spring5入門[STS(Spring Tool Suite)で簡単なWebアプリの典型的なユニットテストの実現方法]

前回は「Spring入門」で、Spring MVCを利用した簡単なWe

Spring5入門[STS(Spring Tool Suite)の環境作成と簡単なWebアプリの作成]

Struts1ももう過去の遺物になり、SAStrutsもEOLとなりも

Selenium入門その6[Selenium3でWebDriver(Java/Junit4)の環境を作成しEdge,Chrome,Firefoxで確認してみる]

Selenium3も3.0.1がリリースされましたし、今後は本格的にS

Selenium利用時のトラブルシューティング方法[クリック編]

Seleniumは便利なテスト自動化ツールですし、今後は更なる利用者の

→もっと見る

Optimization WordPress Plugins & Solutions by W3 EDGE
PAGE TOP ↑