ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

美しいJava開発コミュのコーディング規約

  • mixiチェック
  • このエントリーをはてなブックマークに追加
正確な英単語

returnに括弧はつけない

インデントにはタブを使う(エディタで4文字tabを基本)

空白のあけ方の統一
  引数の,の区切り方、()間の空白
{,},コンマ,演算子,for/if/whileなどの(や)の前後はスペース
例)
  int[] nn = new int[] {
    2, 3, 3, 58
  };
  void testFunction(int a, int b, int c) {
    if (true) {
     func(1, 3, 3);
      for (int i = 0; i < 100; i++) {
        l += 3 * a + b;
      }
    } else if (false) {
    } else {
    }
    return 3 + l;
  }
public class A extends Applet {
}

変数の命名規則
  変数、メソッド名は小文字単語を使う
二単語以上になる場合、二単語目移行の一文字目は大文字にする
  ex) veryLongWord
  定数は、大文字をアンダーバーでつなげる
  ex) static final int CONSTANT_VALUE = 3;

変数の宣言は使う前に
  変数は使用する直前に宣言(可読性、メモリ節約高速化)
必要であればブロックで囲んでスコープを限定

配列の宣言は型のほうに次元をつける
誤)int card[][][];
  正)int[][][] card;

メソッド名は小文字、一文字大文字接続
誤)public boolean judgevanish()
正)public boolean judgeVanish()

演算子の後はスペース
誤)i=3*N+2;
正)i = 3 * N + 2;

括弧のスタイルは、短いものを採用
誤)
if(htcd[i][j]<=0)
{
viscd[i][j]=NoCd;
htcd[i][j]=0;
}
else
{
viscd[i][j]=card[i][j][htcd[i][j]-1];
}
正)
if (htcd[i][j] <= 0) {
viscd[i][j] = NoCd;
htcd[i][j] = 0;
} else {
viscd[i][j] = card[i][j][htcd[i][j] - 1];
}

インスタンスメソッドを使わないものは積極的にstatic
誤)
private int nextcard()
{
return (int)(Math.random()*((double)MaxN+1.0))+MinN;
}
正)
private static int nextCard() {
return (int)(Math.random() * ((double)MAX_N + 1.0)) + MAX_N;
}

変数は使うところで宣言する
誤)
  for(i=0;i<MS;i++)
    van[i][i]=true;
正)
  for (int i = 0; i < MS; i++) // このiはforのループ内のみ有効になります
    van[i][i] = true;

if / for 以降が単行の場合でも中括弧をつけるように心がける

コメント(57)

「比較式で定数を左側に置く」というのは、昔のCコンパイラでもエラーとして検出できるから、というので出てきた技ではないでしょうか。今どきのコンパイラなら、ifの式の中で代入していると警告が出るはず。

個人的には、定数が左にあると気持ち悪いというか、時代遅れな感じがします。
時代遅れかどうかはともかくとして、
・人間はささいまなまちがいをよく犯す
ということを意識した防衛的な書き方なので「比較式で定数を左側に置く」書き方は個人的に好みです。

1行も書かないことが理想です、書かなければバグもできないですしねw
既読でしょうが、このへんも参考にしてます。

Javaコーディング標準オブジェクト倶楽部バージョン
http://www.objectclub.jp/community/codingstandard/CodingStd.pdf

電通国際情報サービス版Javaコーディング規約2004
http://www.objectclub.jp/community/codingstandard/JavaCodingStandard2004.pdf
等号による比較式で、定数を左側に置くメリットよりもデメリットのほうが大きい、というのをかなり昔(だからC言語向け)に読んだ気がするのですが、気のせいかもしれません。理由も覚えていません。

C#ではifの条件式の結果にtrueかfalseしか認めていないとか。まあこれは言語仕様であって、コーディング規約ではないですね。
言葉足らずで済みませんでした。。。

私もC言語なら納得いくのですが、Javaでは「x=0」は0を返すので、条件式に整数を取るCと違って条件式にbooleanしか許さないJavaではコンパイルエラーになるはずなので、つまり「このようなバグをコード中から見つけるのは困難である」というこの資料の主張はJavaの言語仕様を知らずに書かれたのではないか、ということが質問の意図でした。

たまたま開いたところにあったので、他にも同じようなものが沢山あるんじゃないかと・・・でも他は概ね大丈夫そうでしたが。

Javaでもbooleanの定数ではこのような問題は一応起きますが、CやC++を知らない人にはかなり意味不明ではないでしょうか。
javaだと==と=の間違いより、equals()の間違いをよく見ますよね。==による比較は原則禁止とした方がよいのかも。intの比較をする場面は限定的だし。

うちだと、定数を左に置く比較式は可読性を下げるという理由で極力使わないように指導しています。

NullPointerException予防として、Stringの比較時、

str.equals("XXX") ではなく
"XXX".equals(str) を使うべきだ。

という話もよく見るのですが、同様の理由で疑問に思っています。(意味はあるので、直せとは言っていませんが)

それはそれとして、checkstyleとかの規約チェッカ、便利ですね。うちはEclipse3.0に最初からついているものと、ParaSoftのjtestを併用してます。
==による変数と定数の比較は、右左どちらに配置しても等価な式なので、可読性を論点にするの適切だと思いますが、

> str.equals("XXX") ではなく
> "XXX".equals(str) を使うべきだ。
> という話もよく見るのですが、同様の理由で疑問に思っています。
> (意味はあるので、直せとは言っていませんが)

は、そもそも挙動そのものが違うので、可読性を論点になさらないのがよろしいのではないでしょうか?

思慮深いコーディングにおいては、それぞれは使い分けられると思います。
「NullPointerException予防」ってなんだろ・・・初めてききました。

想定していないことでも、落ちないようにする予防でしょうか?なんか嫌な考え方だなあ
str.equals("XXX")
は、strがnullの可能性がある場合
str != null && str.equals("XXX")
と書かなければいけませんが
"XXX".equals(str)
であれば、strがnullであるかどうか気にしなくていいという利点がありますね

なので、基本的には、変数先、定数後のスタイルを使いますが、文字列比較の場合は、逆のスタイルを使ったりもします

意味は、コーディングスタイルより優先事項かな
null と 非nullは 全く別の状態であるのだから、同一の条件式内で評価するのは意味的に美しくない記述ではないかなあ。

str != null && str.equals("XXX")
この記述が必要なら、それはもっと低位のデータ構造や設計思想が間違ってるんじゃないかしら・・・
nullの話が出たところで、一つお題を。

Stringをパラメタに持つメソッドを作るとしますよね?
ほとんどの場合、Nullは想定していないと思うのですが、
規約では「どう作るべき」とするのが妥当でしょうか?
まず、呼び出し側でnullでないことを保証すべきか、メソッドで適切に処理するかを決めます。

呼び出し側で保証すると決めた場合は、Javadocに事前条件として書いておく、と。メソッドで処理する場合は特に書かなくてもよい?
JavaDoc読まずに他人の作ったものをなんとなくコーディングして正常系が動けばOK、という人にはどんな規約も無力。啓蒙あるのみ。

メソッド内で引数のnull判定をしてNullPointerExceptionを自前でthrowするよな場合はRuntimeExceptionでもthrowsとか書いたほうが良いと思います。

メソッド内で引数のnull判定をして、nullなら初期値を与えるとか、nullならfalseを返すとか、null時の動作が規定されてるならJavaDocに挙動を明記するべきです。

メソッド内で他クラスのメソッドに引数を渡す場合も、呼び出すメソッドがnullをどう扱うのか(例外を投げる、初期値を与える、その他)によって、自メソッドの実装に関わらずnull時の挙動を明記するべきでしょうね。

ユーティリティクラスの場合、null時の挙動は定義し、明記されるべきでしょう。
逆に、業務ロジック等でいちいちそんな細かいところまで面倒見れない場合は、「入力チェックでnullを許可しないフィールドなら画面にメッセージを出して、業務ロジックは呼び出さない。」のようなフレームワークレベルでnullをブロックする仕掛けが有効と思います。
確かC++では「参照」と「ポインタ」は文法的に区別されていて、
「ポインタ」を受け取るメソッドは「ポインタ」のNULL値チェックを
するのがお約束、一方「参照」ではNULLが入ってこないように
文法的に制約されていたと記憶しております。

つまり、C++では参照変数の差す先に確実に対象があることが
約束されているかいないかで「参照」と「ポインタ」
という用語も使い分けれられていて、御存知のように
Javaにはもちろんそのような用語の区別はないわけで、
チェックするかしないかをどちらかの規約に完全に
倒すのはC++で言う「参照」か「ポインタ」のどちらかだけで
実装するような感じでしょうか(←不可能ではないけど大変)。

しんさんの「どう作るべきか」については、それを
publicなメソッドとして提供する場合は不特定多数の
開発者に使われる可能性を考慮してnullに対して適切に
振舞うようにしておかなければならないと思いますが、
そうでない場合はクラス内やパッケージ内のポリシーに
従っていれば十分なのではないかと思います。

ただし、パッケージの提供側ではnullを厳密に管理しておいて
予期せぬところで漏れ出さないようにしておくことは必要で、
nullやNullPointerExceptionの漏れ出てくるパッケージは
使いたくないのがパッケージ利用者の心情かと...
しかし、Stringに限らず一般のオブジェクトでも、余計なオブジェクトを作らないため、あるいはパフォーマンスを上げるため、nullを許すようにしたい局面があります。

なので結局はJavaDocの記述、関数側での適切なassert、nullのケースを含めたJUnit等のテスト、を合わせることが必要でしょう。いくら規約を定めても、人間のやることなので最終的には実際に動かさないと安心はできません。

また、C++で参照にNULLが入らないと制約されている、というのは誤りです。たとえば、

foo(X* ptr) {
X& ref = *prt;
...
}

という書き方は何の問題もないのでNULLのこともありえます。
どちらが引き数をチェックするのかを「明示」すべき、というつもりでした。

まったく別の話になりますが、クラスの中でメソッドの記述順序はどうしますか?
・コンストラクタ、デストラクタ、public、…、private
・アルファベット順
・実行されそうな順
・順序に悩むのはクラスが巨大化している証拠なのでリファクタリングする
などなど。
>まったく別の話になりますが、クラスの中でメソッドの記述順序はどうしますか?
そのクラスの役割を理解するのに最も重要なメソッドから記述しますね。必然的にpublicなものが多いです。
同時に、「見りゃわかるだろ」というような簡易なメソッドは後半にコメントもなくずらっと並んでいます。

ちなみに、僕の好きな言葉に
「ソースコードはそれを読む人のために書かれるものである。たまたまそれがコンピュータで実行できるにすぎない」
というのがあります。読みやすさに注意を払うことは重要だと思います。
JavaDocと同じに Field>Constractor>Method の順
> また、C++で参照にNULLが入らないと制約されている、
> というのは誤りです。たとえば、

なるほど...私は間違えて覚えていたようです。
ということは、参照はチェックしなくてよいというのは
単なる規約(スタイル)だったようです。

一応、NULLをチェックするにはいったんポインタに戻せば
できるわけですが、そんなことをする必要のないように
参照は何かを差していることを保証しておけということ
でしょうか。前後しますが、

> なので結局はJavaDocの記述、関数側での適切なassert、
> nullのケースを含めたJUnit等のテスト、を合わせることが
> 必要でしょう。いくら規約を定めても、人間のやることなの
> で最終的には実際に動かさないと安心はできません。

御意です。
あと、NullPointerExceptionの出てくる背景、嫌われる
背景には、メソッドの呼び出し順序などの規約が守られて
いなかったり、同期が取れていなかったりという原因の特定の
難しい問題になっていることも多そうなので、その場面でも
作っておいたテストは資料として役立つと思います。
フィールドを最後に持ってくるスタイルがありますが、あれには何か合理的な理由があるのでしょうか?

フィールドを先頭に持ってくるのは、クラスの取りうる状態が目に入りやすいというあたりかと思いますが、昔のC言語などの関数の宣言のスタイルを踏襲しているということもなくもなさそうな感じです。

>まったく別の話になりますが、クラスの中でメソッドの
>記述順序はどうしますか?

ロジックが重要なクラスでは、私も編集の頻度の高い重要なメソッドほど上の方に持ってきます。あと呼び出し関係のあるものが隣り合っていた方が読みやすい(スクロールの手間が少ない)ということはあると思います。
書き忘れましたが参照のご指摘ありがとうございます>rosarioさん
メソッドの並びについて、参考になりました。僕の場合はコンストラクタから始めて呼ばれる順に並べてみたり、publicを先にしてみたりしています。で、いろいろ編集しているうちにごちゃごちゃに…。
メソッドの順はクラスを構成する要素としての重要度の順であるべきではないでしょうか。逆に言うと、メソッドの順で、重要度を表現するべきなのかもしれません。

例えば、パターンを使っているクラスであれば、パターンを構成するメソッドを先に置くべきだと思いますし、ユーティリティクラスであれば、ABC順の方が見やすいかと。

コンストラクタやgetInstance()メソッドは、「クラスの生成方法」を表現しているという理由で、重要度が高い、最初に持ってくるのではないでしょうか。

通常はpublicの方が重要でしょうが、もし、protectedの方が重要なクラスがあるとすれば、それは前に持ってこられるべきだと思います。(あまり想像できませんが)
新しいお題を。

public
protected
package private
private

の使い分けの規約はどうあるべきでしょう?

「理想的にはこうあるべき」 という話と、
「現実にはこうなっていると便利」 という話が
食い違うことも多いと思います。

例えば、
・publicにした方が単体テストに便利
・protectedにしておけば、サブクラスでオーバライドできる

など。

うちだと、package privateを禁止している以外には
特に規約は作っていません。
パッケージプライベートを禁止している理由ってなんでしょう? JUnitでユニットテストするときに同じパッケージを指定しておけば、publicでなくパッケージプライベートでもアクセスできてよいのですが。
>パッケージプライベートを禁止している理由ってなんでしょう?

あまり深い理由はないです。
package privateを使う積極的な理由を提示されれば、
規約を変えてもよいと思っています。

別の規約で、テストクラスはパッケージを分ける決まりにしています。これは、jarを作るビルドスクリプトの都合です。
クラスが実行可能な処理を記述しているものがインターフェイスなので、
それに対して public を付けるのは冗長な気がするので、わたしは記述しませんね。
ちなみにJLSでは、interfaceのmethod宣言では
abstractやpublicをつけないことを推奨している
みたいですね。

http://www.y-adagio.com/public/standards/tr_javalang2/interfaces.doc.html#78651
http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html#78651
ParaSoftのチェックツールでは
「publicはつけない」ことがルールにありました。

>インターフェイスのメソッドの定義
Singletonなどのprivateなコンストラクタを持つクラスって、finalなクラスにしますか?

僕は、privateなコンストラクタをもつということは、必然的にサブクラス化できないのでfinalは冗長だと思うのですが、final classで明示的に定義したほうが、素敵なんでしょうか?

みなさんどうですか?
> 55: fuzzybsd

派生できないことをjavadocで明示するためにも、
finalを明記した方がいいと考えます。
>たぁぼさん
なるほど、確かにJavadocで明示されることは重要ですね。
納得です。

今度からfinalつけるようにしようかな(^_^;)

ログインすると、残り24件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

美しいJava開発 更新情報

美しいJava開発のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング