TL;DR
- 変数名にオブジェクト名を使用してしまうと、変数のスコープ内でそのオブジェクトの静的メソッド、静的変数が使用できなくなってしまう。
はじめに
ApexにはJavaにはないApex特有の落とし穴があります。
以下の書き方をよく目にしますが、いずれも避けるべき書き方です。
User user = new User(Id = UserInfo.getUserId());
Order order = new Order();
Result result = validateInput();
つまり、変数名にオブジェクト名を小文字にしただけのものを使ってはいけないということです。
なぜなら、場合によってはコンパイルエラーになるからです。
通常、エラーにならないので見落としがちですが、Enumだと確実にエラーになります。
public with sharing class Class001 {
public enum Enumtest {HOGE}
// Ok
private void method001(Enumtest e) {
System.debug(Enumtest.HOGE);
}
// NG
// classes/Class001.cls: Static field cannot be referenced
// from a non static context: HOGE from the type Class001.Enumtest (Line: 13)
private void method002(Enumtest enumtest) {
System.debug(Enumtest.HOGE);
}
}
なぜエラーになるのか、例をあげて説明したいと思います。
例
Apexクラスの場合
以下のクラスがあるとします。
public with sharing class SampleClass {
public static void staticMethod001() {
System.debug( LoggingLevel.DEBUG, 'hello' );
}
}
次の記述はコンパイルされます。
SampleClass sampleClass = new SampleClass();
次の例もコンパイルされます。
SampleClass.staticMethod001();
SampleClass sample = new SampleClass();
ただし、次はコンパイルエラーになります
SampleClass.staticMethod001();
SampleClass sampleclass = new SampleClass();
エラーの理由
エラーの内容は Static field cannot be referenced
です。
つまり、インスタンスから静的メソッドを使用することはできないと言っています。
以下の場合も同じエラーが発生します。
String str = '';
str.valuOf(1);
先程の例では、 SampleClass.staticMethod001();
の SampleClass
が、クラスではなく、変数で宣言した sampleclass
と解釈されたということです。
忘れがちですが、Apexは大文字と小文字を区別しません!!
そのため、このようなことが発生します。
Apex なぜ Account account = new Account(); と書いてはいけないのか
SObjectクラスも静的な変数を持っています。
以下のように記述するとエラーになります。
エラーになる可能性がある以上、Account account
のような記述は避けるべきです。
Account account = new Account();
SObjectField token = Account.Name;