静的メソッドとインスタンスメソッド、変数、初期化コード
特徴
静的メソッド、変数、および初期化コードには次の特性があります。
- クラスに関連付けられる。
- 外部クラスでのみ許可される。
- クラスが読み込まれたときにのみ初期化される。
- Visualforce ページのビューステートの一部として転送されない。
インスタンスメソッド、メンバー変数、および初期化コードには次の特性があります。
- 特定のオブジェクトに関連付けられる。
- 定義修飾子がない。
- 宣言されたクラスからインスタンス化された各オブジェクトと一緒に作成される。
ローカル変数には次の特性があります。
- 宣言されたコードのブロックに関連付けられる。
- 使用前に初期化する必要がある。
次の例は、範囲が if コードブロックの持続時間であるローカル変数を示します。
1Boolean myCondition = true;
2if (myCondition) {
3 integer localVariable = 10;
4}静的メソッドと変数の使用
外部クラスの静的メソッドと変数のみを使用できます。内部クラスには静的メソッドや変数はありません。静的メソッドまたは変数を実行するために、クラスのインスタンスは必要ありません。
クラスのオブジェクトが作成される前に、クラスの静的メンバー変数がすべて初期化され、静的初期化コードブロックがすべて実行されます。これらの項目は、クラスに表示される順序で処理されます。
静的メソッドはユーティリティメソッドとして使用され、インスタンスメンバー変数の値に依存することはありません。静的メソッドは、1 つのクラスのみに関連付けられているため、そのクラスのインスタンスメンバー変数の値にはアクセスできません。
静的変数は、Apex トランザクションの範囲内でのみ静的です。サーバ全体または組織全体で静的なわけではありません。静的変数の値は、1 回のトランザクションのコンテキスト内で保持され、トランザクションの境界を超えたときにリセットされます。たとえば、Apex DML 要求によってトリガが何回も起動される場合、これらのトリガ呼び出しを通して静的変数は保持されます。
クラスのインスタンス間で共有された情報を保存するには、静的変数を使用します。同じクラスのすべてのインスタンスが、静的変数の 1 つのコピーを共有します。たとえば、1 回のトランザクションで実行されるすべてのトリガは、関連するクラス内の静的変数を確認したり更新したりすることで、互いに通信することができます。再帰的なトリガは、クラス変数の値を使用して、再帰を終了するタイミングを判断できます。
次のクラスがあるとします。
1public class P {
2 public static boolean firstRun = true;
3}このクラスを使用するトリガは、選択的にトリガの最初の実行を失敗することができます。
1trigger T1 on Account (before delete, after delete, after undelete) {
2 if(Trigger.isBefore){
3 if(Trigger.isDelete){
4 if(p.firstRun){
5 Trigger.old[0].addError('Before Account Delete Error');
6 p.firstRun=false;
7 }
8 }
9 }
10}トリガで定義された静的変数の値は、同じトランザクション内の異なるトリガコンテキスト間 (insert の呼び出し前と呼び出し後など) では保持されません。代わりに、クラスに静的変数を定義して、トリガがこれらのクラスメンバー変数にアクセスし、静的値を確認できるようにします。
クラスの静的変数に、そのクラスのインスタンスを介してアクセスすることはできません。クラス MyClass に静的変数 myStaticVariable があり、myClassInstance が MyClass のインスタンスの場合、myClassInstance.myStaticVariable は不正な表現です。
インスタンスメソッドの場合も同様です。myStaticMethod() が静的メソッドの場合、myClassInstance.myStaticMethod() は不正です。代わりに、クラス MyClass.myStaticVariable および MyClass.myStaticMethod() を使用して、これらの静的識別子を参照します。
1public static void method() {
2String Database = '';
3Database.insert(new Account());
4}内部クラスは、Java の静的な内部クラスのように機能しますが、static キーワードを要求しません。内部クラスは、外部クラスのようにインスタンスメンバー変数を持つことができますが、(this キーワードを使った) 外部クラスのインスタンスへの暗黙的ポインタはありません。
インスタンスメソッドと変数の使用
インスタンスメソッドとメンバー変数は、クラスのインスタンス、すなわちオブジェクトによって使用されます。インスタンスメンバー変数は、メソッド内ではなく、クラス内で宣言されます。インスタンスメソッドは通常、インスタンスメンバー変数を使用してメソッドの動作に影響を及ぼします。
二次元の点を集めるクラスを作成し、それらの点をグラフ上にプロットするとします。次のスケルトンクラスは、メンバー変数を使用して点のリストを保持し、内部クラスを使用して点の二次元リストを管理します。
1public class Plotter {
2
3 // This inner class manages the points
4 class Point {
5 Double x;
6 Double y;
7
8 Point(Double x, Double y) {
9 this.x = x;
10 this.y = y;
11 }
12 Double getXCoordinate() {
13 return x;
14 }
15
16 Double getYCoordinate() {
17 return y;
18 }
19 }
20
21 List<Point> points = new List<Point>();
22
23 public void plot(Double x, Double y) {
24 points.add(new Point(x, y));
25 }
26
27 // The following method takes the list of points and does something with them
28 public void render() {
29 }
30}初期化コードの使用
インスタンス初期化コードは、クラス内で定義される、次の形式のコードブロックです。
1{
2
3 //code body
4
5}クラス内のインスタンス初期化コードは、そのクラスからオブジェクトがインスタンス化されるたびに実行されます。これらのコードブロックは、コンストラクタの前に実行されます。
クラスに独自のコンストラクタを記述しない場合は、インスタンス初期化コードブロックを使用してインスタンス変数を初期化できます。簡単な状況では、通常のイニシャライザを使用します。初期化コードは、静的対応付けの初期化など、複雑な状況にのみ使用します。静的初期化ブロックは、そのブロックを含むクラスにアクセスする回数に関係なく、1 回のみ実行されます。
静的初期化コードは、キーワード static に続くコードブロックです。
1static {
2
3 //code body
4
5}他の静的コードと同様に、静的初期化コードブロックは、クラスの初回使用時に一度だけ初期化されます。
1 つのクラスに、静的初期化コードブロックまたはインスタンス初期化コードブロックのいずれかを、任意の数含めることができます。コード本文のどこに記述しても構いません。Java の場合と同様に、コードブロックはファイルに表示される順序で実行されます。
静的初期化コードを使用して、静的なファイナル変数を初期化したり、値の対応付けなど静的な情報を宣言したりできます。次に例を示します。
1public class MyClass {
2
3 class RGB {
4
5 Integer red;
6 Integer green;
7 Integer blue;
8
9 RGB(Integer red, Integer green, Integer blue) {
10 this.red = red;
11 this.green = green;
12 this.blue = blue;
13 }
14 }
15
16 static Map<String, RGB> colorMap = new Map<String, RGB>();
17
18 static {
19 colorMap.put('red', new RGB(255, 0, 0));
20 colorMap.put('cyan', new RGB(0, 255, 255));
21 colorMap.put('magenta', new RGB(255, 0, 255));
22 }
23}