5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Salseforce】thisキーワードの謎

Last updated at Posted at 2022-03-11

はじめに

Apexにはthisキーワードが用意されています。
this付きで変数にアクセスすることで、その対象変数がクラスのメンバ変数であることを明示できます。(ローカル変数と区別できる)

public class Sample {

  //クラスのメンバ変数
  String color = '赤';

  public void printColor() {
    //ローカル変数
    String color = '青';
    System.debug('ローカル変数color -> ' + color); // 青
    System.debug('メンバ変数 this.color -> ' + this.color); // 赤 
  }
}

上記はプリミティブ型(String)メンバ変数の例となりますが、
一方で、SObject型メンバ変数へアクセスする際、thisキーワードの有無で異なる動きが観測されたので備忘録として残しておきます。

なにがわかったのか?

簡単に言うと、SObject型メンバ変数がNullの場合でも、thisを付けてアクセスするとNullPointerExceptionが発生しないことがわかりました。

まず、以下のコードはNullPointerExceptionが発生します。

public class Sample {

  //クラスのSObjectメンバ変数
  public Contact sampleContact;

  public void printContactName() {
    // sampleContactはNull(非インスタンス)なのでName項目にアクセスできず例外発生
    System.debug(sampleContact.Name); // <- System.NullPointerException: Attempt to de-reference a null object
    System.debug('finish'); // <- 表示されない
  }
}

Sample sample = new Sample();
sample.printContactName();

しかし、以下のようにthisを付与してメンバ変数にアクセスするとNullPointerExceptionは発生しません。

public class Sample {

  //クラスのSObjectメンバ変数
  public Contact sampleContact;

  public void printContactName() {
    // sampleContactをインスタンス化していないが、Name項目を参照可能
    System.debug(this.sampleContact.Name); // <- 結果はNullだが、NullPointerExceptionは発生しない
    System.debug('finish'); // <- 表示される
  }
}

Sample sample = new Sample();
sample.printContactName();

もちろん、thisあり/thisなしの2つは同一データです。

public class Sample {

  //クラスのSObjectメンバ変数
  public Contact con;

  public void printContactName() {
    System.debug(this.con === con); // <- true
  }
}
Sample sample = new Sample();
sample.printContactName();

以上のようにthisキーワードの有無で挙動が異なるのですが、原因は不明です。

その他にも色々試してみました。

1.SObjectメンバ変数のリレーション項目へアクセスしてみる

リレーション項目もthisをつければアクセスできます。もちろん、this無しはNullPointerExceptionが発生します。

public class Sample {

  //クラスのSObjectメンバ変数
  public Contact con;

  public void printContactName() {
    // Contactのリレーション項目Accountの名前にアクセス
    System.debug(this.con.account.name); // <- 結果はNullだが、NullPointerExceptionは発生しない
    System.debug('finish'); // <- 表示される
  }
}
Sample sample = new Sample();
sample.printContactName();

2.メンバ変数をクラス外から直接参照してみる

クラス外からNullのSObjectメンバ変数に直接アクセスした場合、こちらもNullPointerExceptionは発生しないようです。

public class Sample {
    public Contact con ;
}

Sample sample = new Sample();
// Sampleクラスのメンバ変数
System.debug(sample.con == null); // <- true
// 項目
System.debug(sample.con.name == null); // <- true
// リレーション
System.debug(sample.con.account == null); // <- true
// リレーション項目
System.debug(sample.con.account.name == null); // <- true

さいごに

以上、thisキーワードの謎についてでした。
クラスをnewした際にSObjectメンバ変数の初期化のような処理が行われるのだろうか・・🤔?と考えましたが、理由はわかりません・・
とりあえず、
クラス内部からSObject型メンバ変数にアクセスする場合、常にthisキーワードを付与することでNullPointerExceptionが発生しないようになるため、忘れずに付与したいところです。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?