• 締切済み

不正なコードの検出方法

EclipseにてJavaにて開発を行っているのですが下記のような不正なコード (オブジェクトを==演算子で比較して同じ値かどうかを判定)を検出する プラグインがないか探しています。FindBugをインストールしてみましたが検出されませんでした。 下記コードではJavaの仕様によりa,bの値が-127~127であれば同じオブジェクトと判定され、 範囲を超える場合、異なるオブジェクトとみなされる不安定な動きをするため、 警告してくれてもよさそうなものなのですが・・・。 警告してくれるようなプラグインまたはEclipseの設定はありますでしょうか。 Integer a = 1000; Integer b = 1000; if( a == b) { System.out.println("同じ値"); }

  • Java
  • 回答数3
  • ありがとう数2

みんなの回答

  • root139
  • ベストアンサー率60% (488/809)
回答No.3

少なくとも最新(ver.3.0.1)のFindBugsなら、 FindRefComparison が有効になっていればご質問のような箇所は検出されるはずです。 http://findbugs.sourceforge.net/bugDescriptions_ja.html#RC_REF_COMPARISON というか、私の環境の FindBugs では質問のコードの if( a == b) の行にマーカーが付きました。 ちなみに、すでに指摘されている通り、-127~127であれば本当に同じオブジェクトになっていてそれら以外では別オブジェクトになっている訳です。(どんな環境でも100%そうなるとは限らないかも知れませんが・・・) 理由は、Integer.valueOf(int) のソースコードを見ると分かります。 http://docs.oracle.com/javase/jp/8/api/java/lang/Integer.html#valueOf-int-

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.2

#1です。 例えば、質問に書いてあるソースでは >System.out.println("同じ値"); とありますのでメッセージの"同じ値"の意味がわかる人であれば、a == b は実際は同じ値なのかを調べたいので a.equals(b) (または b.eqals(a)) の間違いとわかりますが、"同じ値"の意味のわからない人(日本語が読めないとか)にとってはa == bが警告すべきものなのかどうかわかりません。 まあインスタンス同士を==で比較してるのを無条件に警告するというのもありなのかもしれませんが。

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.1

>下記コードではJavaの仕様によりa,bの値が-127~127であれば同じオブジェクトと判定され、 >範囲を超える場合、異なるオブジェクトとみなされる不安定な動きをするため、 不安定というわけではなく実際に-127~127なら同じインスタンスが使われて、それ以外だと個別にインスタンスが生成されてるだけだと思いますけど。 >警告してくれるようなプラグインまたはEclipseの設定はありますでしょうか。 その部分だけみるならインスタンスが同じかの判定で、おかしいわけではありませんから、さすがにないのではないでしょうか。

unko347
質問者

お礼

ご回答ありがとうございます。 下記の挙動がコーディングの落とし穴となりえるのでコンパイル時に警告が 出てくれればと思った次第です。 >>不安定というわけではなく実際に-127~127なら同じインスタンスが使われて、それ以外だと個別にインスタンスが生成されてるだけだと思いますけど。

関連するQ&A

  • オブジェクトの参照およびハッシュコードについて

     下記のプログラムは任意のクラスMoofおよびStringクラスについてそれらのオブジェクトの参照値とハッシュコードをプリントし、さらにStringオブジェクトの参照値同士の比較をしています。 次の質問に対して分かりやすくご教示ください。 (1)Moofオブジェクトについては参照値そのものの値を出力しているようですが、Stringオブジェクトの場合はオブジェクトの値(abc)が出力されているのは何故ですか (2)参照値の構成は(クラス名+@+16進ハッシュコード)であり、オブジェクト(インスタンス)のあるアドレスを指し示すと聞きました。Stringオブジェクトは2つあってその値はabcで等しいのでハッシュコードも同じになっている訳ですが、もしハッシュコードがアドレスを示すとすると2つのオブジェクトに対してアドレスは1つとなりますが… (3)上の(2)に関連して参照値four、fiveに関するオブジェクトのハッシュコードはともに0x17862で等しいのですが、両者を==演算子で比較するとfalseとなります。 これはどうしてですか。  どなたか詳しい方、よろしくお願いします。 public class EqualsCheckX { public static void main(String[] args) { Moof one = new Moof(8); Moof two = new Moof(8); Moof three = one; int a = one.hashCode(); int b = two.hashCode(); int c = three.hashCode(); String four = new String("abc"); String five = new String("abc"); String six = four; int d = four.hashCode(); int e = five.hashCode(); int f = six.hashCode(); System.out.println("Moof " + " one : " + one + " two : " + two + " three : " + three); System.out.println("String" + " four : " + four + " five : " + five + " six : " + six); System.out.println(); System.out.println("hashCode" + " one : " + Integer.toHexString(a) + " two : " + Integer.toHexString(b) + " three : " + Integer.toHexString(c)); System.out.println("hashCode" + " four : " + Integer.toHexString(d) + " five : " + Integer.toHexString(e) + " six : " + Integer.toHexString(f)); System.out.println(); // String if (four == five) { System.out.println("String : four and five are equal"); } else { System.out.println("String : four and five are not equal"); } if (four == six) { System.out.println("String : four and six are equal"); } else { System.out.println("String : four and six are not equal"); } } } class Moof { private int moofValue; Moof(int val) { moofValue = val; } } C:\MyJava>java EqualsCheckX Moof one : Moof@1ac04e8 two : Moof@765291 three : Moof@1ac04e8 String four : abc five : abc six : abc hashCode one : 1ac04e8 two : 765291 three : 1ac04e8 hashCode four : 17862 five : 17862 six : 17862 String : four and five are not equal String : four and six are equal

  • 注釈処理が明示的にリクエスト

    いつも大変お世話になりありがとうございます。 また、JAVAの質問です。 クラス名'Lesson07'が受け入れられるのは、注釈処理が明示的にリクエストされた場合のみです というエラーが出ます。 どうすればいいか教えてください。 ご回答のほど宜しくお願い申し上げます。 import java.io.Console; public class Lesson07 { public static void main(String[] args) { long a; long b; long answer; Console console = System.console(); System.out.println("2つの値で足し算を行います"); System.out.println("1つ目の値を入力してください"); a = Integer.parseInt(console.readLine()); System.out.println("2つ目の値を入力してください"); b = Integer.parseInt(console.readLine()); answer = a + b; System.out.println(a + "足す" + b + "の答えは" + answer + "です"); }

    • ベストアンサー
    • Java
  • JAVA 二分探索木トラバーサルのコンパイル時警告

    下記のTreeMaptest01.javaをコンパイルした時、次のような警告が出ます。 この警告が出ないようにする方法を教えてください。 よろしくお願いします。 % javac -Xlint:unchecked TreeMaptest01.java TreeMaptest01.java:92: 警告:[unchecked] 無検査変換です 検出値 : decorder 期待値 : java.util.Comparator<? super java.lang.String> TreeMap<String,String> s = new TreeMap<String,String>(new decorder()); ^ 警告 1 個 /*=========TreeMaptest01.java=========================================== import java.util.*; class decorder implements Comparator { public int compare(Object obj1, Object obj2) { int c = ((String)obj1).compareTo((String)obj2); return -c; } } class TreeMaptest01 { public static void main(String args[]) { // 空のマップを作成。 TreeMap<String,String> tm = new TreeMap<String,String>(); // キーと値の組を追加。 tm.put("C","Car"); tm.put("A","Airplane"); tm.put("B","Book"); tm.put("E","Earth"); tm.put("D","Door"); // キーと値のすべての組を昇順にたどる。 System.out.println("キーと値のすべての組を昇順にたどる"); Set a = (Set)(tm.keySet()); Iterator ia = a.iterator(); while( ia.hasNext() ) { Object key = ia.next(); System.out.println("キー:" + key + " 値:" + (String)tm.get(key)); } System.out.println(); // 空のマップを作成。 // ここでエラー(警告が出る) TreeMap<String,String> s = new TreeMap<String,String>(new decorder()); // キーと値の組を追加。 s.put("C","Car"); s.put("A","Airplane"); s.put("B","Book"); s.put("E","Earth"); s.put("D","Door"); // キーと値のすべての組を降順にたどる。 System.out.println("キーと値のすべての組を降順にたどる"); Set b = (Set)(s.keySet()); Iterator ib = b.iterator(); while( ib.hasNext() ) { Object key = ib.next(); System.out.println("キー:" + key + " 値:" + (String)s.get(key)); } } } =======================================================================*/

  • 表どうしで演算するSQLについて

    SQLについて質問です。 コードと値(数値型)で構成されている表が3つある(A、B、C)とします。 そして、下記のようにコードをキーに値の演算をしたいと 思っています。 select A.値 - B.値 + C.値 as z from・・ この時にコードがない時(たとえばAにB,Cと同じコードない時)は、A.値(=0)+B.値(=3)+C.値(=7)のように0をセットして、要は3つのの表の最大レコード数分の演算値を取得したいのですが、どのようにSQLを記述すれば良いでしょうか?

  • ユーザー入力値を足し算する

    import java.io.*; public class sampleD4L2 { public static void main(String[] args) { //入力データー読み込みようオブジェクトを作成 BufferedReader myReader = new BufferedReader( new InputStreamReader(System.in), 1); try{ //開始メッセージの表示 System.out.println("A+Bの足し算を行います"); //Aの値の入力を促す System.out.println("Aの値を入力してください"); //Stringクラス型の変数を宣言し読み込んだ入力データーを代入 String myString = myReader.readLine(); //String型に入力した値をint型の変数に代入 int intA = Integer.parseInt(myString); //Bの値の入力を促す System.out.println("Bの値を入力してください"); //Stringクラス型に読み込んだ入力データーの代入 int intB = Integer.parseInt(myString); //A+Bを計算し、intAnswerに代入 int intAnswer = intA + intB; //メッセージを合成して表示 System.out.println("A+Bを計算すると" + intAnswer + "になります"); //エラー処理ブロッグ }catch (IOException e) { System.out.println("エラーが発生しました"); } } } 上のソースは本通に写したんですが、Bの値が入力せずA+Aの計算になっています。どこがいけないのでしょうか?

  • Javaのハッシュコードについて

    SunJava2認定ガイドでJavaを勉強している初心者ですが、「オブジェクトとコレクション」を説明した章(第7章)に、 ・2つのオブジェクトがequals()メソッドで等しいと判定された場合、 両者のハッシュコード値は同じでなければならない ・2つのオブジェクトを等しいと見なすためには、両者のハッシュコー ドも等しくなければならない という記述がありますが、この2つのオブジェクトのハッシュコードというのは2つのオブジェクトを指すそれぞれの参照変数であると理解していいのでしょうか? … もしそうであるなら、2つのオブジェクトが等しいという意味は、2つのオブジェクトは同一であるということを意味することになるのでしょうか  どなたかご教示ください

  • c言語 等価演算子(==)について

    等価演算子(==)は、ポインタの指すオブジェクトが同一あるかないの判定する演算子。  故に下記の例、*sc1 == sc2 は、sc1とsc2の値(オブジェクト)を比較しているのですか教えてください。      char *sc1 = s1; char *sc2 = s2; *++sc1 == sc2;

  • 論理和演算子を使って、三項演算子のような簡易分岐ができるようなコードを

    論理和演算子を使って、三項演算子のような簡易分岐ができるようなコードを書けるという テクニックがあるというのを本で読んで試して見たのですが、うまくいきません。 本に書いてあるコードはこんな感じです。 bがなければ、cのプロパティであるdを、それもなければ、500をaに代入する。 bを削除するとdが代入されると思ったのですが、エラーになってしまいます。 //var b = 1; var c = new Object(); c.d = 2; var a = b || c.d || 500 ; どうやったらうまくいきますでしょうか?よろしくお願いします。

  • セッションオブジェクトにリンクするプログラムです。

    どこが間違ってますか? コンパイルできないんです。。。 セッションオブジェクトを使って カウンタを作り、リンクからカウンタの値を 変更できるようにしているつもりです。 SessionCount.java <前略> HttpSession session = req.getSession(); Integer count; count = (Integer)session.getAttribute("count"); if (count == null){ count = new Integer(1); }else{ count = new Integer(count.intValue() + 1); } session.setAttribute("count", count); out.println("<html>"); out.println("<head><title>Session Test</title></head>"); out.println("<body>"); out.println("Count = " + count.intValue());//確認用 out.println("<A HREF = "URL/SessionCount" onClick = "count=count+1">続行</A>"); out.println("<A HREF = "URL/SessionCount" onClick ="count=0">リセット</A>"); <後略>

    • ベストアンサー
    • Java
  • javaにおけるCSV出力時の文字コード改行コード

    JavaでCSVを出力する処理を作りました。 下記コードだとUnix環境で文字コードSJISで改行コードLFで出力されますが、 Windows環境でもUnix環境でも一律、文字コードSJISで改行コードCRLFで出力されるようにしたいです。 何かいい方法はありませんでしょうか。 なお、printlnで出力している行が多い為、 bw,Print("日付" + 変数A + \r\n); というふうに一行づつ変更するのは避けたいと思っております。 try{ PrintWriter bw = new PrintWriter(new BufferdWriter(new OutputStreamWriter(new FileOutputStream(/tmp/test.csv),"SJIS"))); bw.println("日付" + 変数A); bw.println("氏名" + 変数B); ・ ・ ・ }catch(Exception e){ // ログに出力 }

    • ベストアンサー
    • Java

専門家に質問してみよう