JavaのStringでequalsによる等価判定を行う場合に、
比較対象となる定数は左側にする理由はNullPointerExceptionを回避するためです。
以降、NullPointerExceptionが発生する仕組みと、
定数を左側にすることでどのように回避できるのかについて解説していきます。
Stringクラスのequalsメソッド
Stringクラスに定義されているequalsメソッドです。
この中身も含めて解説していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } |
定数を右に置いた場合
1 2 3 4 5 6 7 8 9 10 11 |
public class EqualsTest { public static void main(String[] args) { String str = null; if(str.equals("A")) { System.out.println(str); } } } |
<実行結果>
Exception in thread "main" java.lang.NullPointerException
at string_test.EqualsTest.main(EqualsTest.java:13)
<解説>
「Stringクラスのequalsメソッド」を見て下さい。
7行目:int n = value.length;
ここが、NullpointerExceptionの発生箇所です。
比較元のStringオブジェクト(str)のフィールドであるvalueがNullなので、
ここでNullPointerExceptionになります。
定数を左に置いた場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class EqualsTest { public static void main(String[] args) { String str = null; // 左に置いた場合 if("A".equals(str)) { System.out.println("Aです。"); }else { System.out.println(str); } // String型でも値がNullだと、型比較でFalseになる・・・(A) if (str instanceof String) { System.out.println("str is String"); }else { System.out.println("str is not String"); } } } |
<実行結果>
null
str is not String
<解説>
比較対象の文字列(Null値)を左にすると、「Stringクラスのequalsメソッド」の
5行目:if (anObject instanceof String) { でFalse判定となります。
7行目は実行されませんので、20行目でreturn false; となり、正常に機能します。
※5行目がFalseになるのは、
String型同士の比較であっても値がNullの場合はFalseになるためです。((A)参照)。
どうしても左側にNullが入る可能性を排除できない場合
比較する値が左右ともに変数で、左側にNullが入る可能性を排除できないような場合は、
try~catchなどの対処が必要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class EqualsTest { public static void main(String[] args) { String str1 = null; String str2 = null; // 左に置いた場合 try { if(str1.equals(str2)) { System.out.println("一致しています。"); } }catch(NullPointerException ne) { System.out.println("左側の変数がNullのため、評価できません。"); ne.printStackTrace(); } } } |
<実行結果>
左側の変数がNullのため、評価できません。
java.lang.NullPointerException
at string_test.EqualsTest.main(EqualsTest.java:11)
<解説>
Null同士だからTrueが返ってくるわけではありません。
左側の値がNullなので、NullPointerExceptionが発生するため、
try~catchで例外を補足します。
他にも、Nullだったら強制的に空値(“”)で初期化するという方法も使えると思います。
大事なことは、左側にNullが入り込む余地があるなら必ず何らかの対処をするということです。
まとめ
・比較する変数を左|定数を右に置くと、NullPointerExceptionが発生する原因になる。
・定数を左|比較する変数を右に置くと、False判定として機能する。
・左側にNullが入る可能性がある場合、try~catchなどで対処する。