第12章 java修飾子
修飾子の種類やその挙動について説明します
homepage
# **java修飾子** *** <br> ## **1.メンバ変数定義時に付与できる修飾子** ※ 修飾子は上から定義する順に並んでいます。 <table border="1"> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th>修飾子</th> <th>説明</th> </tr> <tr> <td>アクセス修飾子</td> <td>アクセス修飾子を指定することにより、メンバ変数を他のクラスから参照できないなどを指定できるようになります。</td> </tr> <tr> <td>static</td> <td>メンバ変数がインスタンス変数ではなく、<b>クラス変数</b>であることを表します。</td> </tr> <tr> <td>final</td> <td>finalをつけると変数に一度値が生成されるとその値を変更できず定数として扱われます。</td> </tr> <tr> <td>transient</td> <td>シリアライズすべきでないメンバ変数を表します。</td> </tr> <tr> <td>volatile</td> <td>メンバ変数に対して、コンパイラが何らかの最適化を施すことを防止します。</td> </tr> </table> <br> ## **2.メソッド定義時に付与できる修飾子** ※ 修飾子は上から定義する順に並んでいます。 <table border="1"> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th>修飾子</th> <th>説明</th> </tr> <tr> <td>アクセス修飾子</td> <td>アクセス修飾子を指定することにより、メソッドを他のクラスから参照できないなどを指定できるようになります。</td> </tr> <tr> <td>static</td> <td>メソッドがインスタンスメソッドではなく、<b>クラスメソッド</b>であることを表します。</td> </tr> <tr> <td>abstract</td> <td>処理を実装しないメソッド(抽象メソッド)を生成したい時に使用します。</td> </tr> <tr> <td>final</td> <td>finalを使用した場合、そのメソッドはサブクラスでオーバーライドすることができません。</td> </tr> <tr> <td>native</td> <td>C言語など他の言語で記述されたプログラムをJavaプログラム内で使用したい時に使います。使用したいプログラムにnativeを付け定義します。</td> </tr> <tr> <td>synchronized</td> <td>スレッドを複数同時に走らせる際に同じデータに対し複数のメソッドが呼び出される場合があります。そのような場合、安全にメソッドが実行されるためにsynchronizedを使用します。</td> </tr> </table> <br> ## **3.アクセス修飾子** ### **3-1.アクセス修飾子の種類** 指定できるアクセス修飾子を以下に記載します。クラス定義時に指定できるアクセス修飾子は「public」と「指定無し(デフォルト)」のみです。 <table border="1"> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th>アクセス修飾子</th> <th>クラス</th> <th>メンバ変数</th> <th>メソッド</th> <th>コンストラクタ</th> </tr> <tr> <td>public</td> <td>○</td> <td>○</td> <td>○</td> <td>○</td> </tr> <tr> <td>protected</td> <td>×</td> <td>○</td> <td>○</td> <td>○</td> </tr> <tr> <td>指定無し(デフォルト)</td> <td>○</td> <td>○</td> <td>○</td> <td>○</td> </tr> <tr> <td>private</td> <td>×</td> <td>○</td> <td>○</td> <td>○</td> </tr> </table> <br> ### **3-2.アクセス修飾子の使用方法** アクセス修飾子の使用方法についての説明します。 • **public**と指定すると、どこからでも参照できます。 • **protected**と指定すると、そのクラスを継承したサブクラスからしか参照できません。 • **修飾子を省略する**と、同じパッケージのクラスからしか参照できません。 • **private**と指定すると、そのクラスの中からしか参照できません。 <table border="1"> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th rowspan="2">アクセス修飾子</th> <th colspan="3">自パッケージ</th> <th colspan="2">他パッケージ</th> </tr> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th>自クラス</th> <th>サブクラス</th> <th>他クラス</th> <th>サブクラス</th> <th>他クラス</th> </tr> <tr> <td>public</td> <td>○</td> <td>○</td> <td>○</td> <td>○</td> <td>○</td> </tr> <tr> <td>protected</td> <td>○</td> <td>○</td> <td>○</td> <td>○</td> <td>×</td> </tr> <tr> <td>指定無し(デフォルト)</td> <td>○</td> <td>○</td> <td>○</td> <td>×</td> <td>×</td> </tr> <tr> <td>private</td> <td>○</td> <td>×</td> <td>×</td> <td>×</td> <td>×</td> </tr> </table> <br> #### **例** [Television.java] ``` package JSample; public class Television{ private int channelNo; private void setChannel(int newChannelNo){ channelNo = newChannelNo; System.out.println("新しいChannelNo=" + channelNo); } } ``` [JSample12_1.java] ``` package JSample; public class JSample12_1{ public static void main(String args[]){ Television tv1 = new Television(); tv1.setChannel(1); } } ``` #### **実行結果**(コンパイルの段階でエラーとなります。) Exception in thread "main" java.lang.Error: Unresolved compilation problem: <br> メソッド setChannel(int) は型 Television で不可視です<br> <br> at JSample.JSample11_6.main(JSample11_6.java:7) <br> ## **4.static** メンバ変数、メソッドを定義する際、static修飾子が付与されたものを**クラス変数**、**クラスメソッド**、static修飾子が付与されていないものを**インスタンス変数**、**インスタンスメソッド**といいます。 **mainメソッド**はインスタンスを生成する前に実行する必要があるため、static修飾子を付けて定義しています。 <br> **static変数**とはクラス対応に1つだけ存在する変数です。オブジェクトごとに存在するインスタンス変数とは異なりオブジェクトを生成しなくてもアクセスは可能です。 <br> **static変数**はクラス単位で管理したいときに便利な変数です。 #### **例** クラス変数の参照方法を例示します。 <br> [ExClass.java] ``` package JSample; class ExClass{ //クラス変数の宣言 static int standardSize; //クラス変数に値を設定 void setSize(int num) { standardSize = num; } } ``` [JSample12_2.java] ``` class JSample12_2 { public static void main(String[] args) { ExClass ins1 = new ExClass(); //クラス変数に100を設定 ins1.setSize(100); ExClass ins2 = new ExClass(); //クラス変数に300を設定 ins2.setSize(300); //クラス変数は、インスタンス間で値を共有するため、 //一番最後に設定された300が表示される System.out.println(ins1.standardSize); System.out.println(ins2.standardSize); System.out.println(ExClass.standardSize); } } ``` #### **実行結果** <pre> <iframe src="javascript:'<html> 300<br> 300<br> 300 </html>'" height="100"></iframe> </pre> 静的メンバーを利用する場合の注意点を、以下にまとめておきます。 (1)静的メソッドからthisにはアクセスできない 静的メソッドでは、いわゆるインスタンスはありませんので、当然、インスタンスを示すthisにもアクセスできません。 (2)静的フィールドの利用は限定的に 静的フィールドは、インスタンスフィールドとは違って、内容を変更した場合にもすべてのインスタンスに影響してしまいます(いわゆるグローバルな変数です)。静的フィールドの濫用はそのままクラス間の依存が強くなり、結果、コードの可読性が困難になる場合もあります。 一般的には、静的フィールドは読み取り専用の用途で利用することをお勧めいたします。 #### **例** クラス変数、クラスメソッドの参照方法を例示します。 <br> [JSample12_3.java] ``` package JSample; class JSample12_3 { //クラスメンバ変数の宣言・生成 static String classV = "クラス変数classV"; //クラスメソッドの宣言 static void classM() { System.out.println("クラスメソッドclassM"); } public static void main(String[] args) { //クラス名を通してクラス変数を参照 System.out.println(JSample12_3.classV); //クラス名を通してクラスメソッドを参照 JSample12_3.classM(); } } ``` #### **実行結果** <pre> <iframe src="javascript:'<html> クラス変数classV<br> クラスメソッドclassM </html>'" height="80"></iframe> </pre> <br><br> *** > **練習** >> **問題** [AccessTest.java] ``` package test; public class AccessTest{ public void a(){ System.out.println("public"); } protected void b(){ System.out.println("protected"); } void c(){ System.out.println("修飾子なし"); } private void d(){ System.out.println("private"); } } ``` [JEx12_1.java]をコンパイルしてみましょう。 <br> ``` package JSample; import test.AccessTest; public class JEx12_1{ public static void main(String[] args){ AccessTest at = new AccessTest(); at.a(); at.b(); at.c(); at.d(); } } ``` <br> <br> >> **問題** [JEx12_2.java] ``` public class JEx12_2 { public static void main(String[] args) { Dog dog1 = new Dog(3); Dog dog2 = new Dog(5); System.out.println(dog1.age); } } class Dog { static int age; public Dog(int age) { this.age = age; } } ``` #### **実行結果を選択してください** 1. 「3」と表示 2. 「5」と表示 3. 何も表示されない 4. コンパイルエラー 5. 実行時エラー
content
戻る