初級者がやりがちなコーディングミスについてまとめたい
気づいたときに「くそっくそっくそぉおおおおお」ってなるやつをまとめました。
やりがちなうっかりミスなので、そういうパターンもあるんだなぁ…という学びにしてください。
タイピングミスや表記ゆれ
ローマ字変数ほどやりがち。
あと、「しゅ」とか「ちゅ」とか表記ゆれでミスりがち。
案外これだけのことだけど、MVC周りのつながりが破綻したりして小一時間かけてデバッグしたりする羽目になる。
どこでデータのやりとりが途切れてるのか、それぞれにポイントを張っておくと見つけやすい。
String shuro = "就労" // 亜種でsyuroやshurouとかもいる。統一してほしい…
String chukan = "中間" // tyukanと表記ゆれする
String toujoutorihiki = "通常取引" // タイプミスのままDBのカラムに登録されてたことあって泣いた
getterの変数名と異なるスペルで呼び出し
Beansクラスで記載しているのとスペルが違うせいでViewに表示されないパターン。
WEBアプリ開発初心者がたまにやりがち。
public class User {
    private String userName;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
	<p>ユーザ一覧</p>
     <%-- JSPのcタグって今日び使うんだろうか…? --%>
    <c:forEach var="user" items="${users}">
        <!-- getterはuserNameなのにVIEWは N が n になってるので変数名が一致せず参照できない --!>
        <c:out value="${user.username}" /><br/>
    </c:forEach>
</body>
</html>
うっかりカンマの打ち間違い
いまだによくやる(恥ずかしい)
特にSQLでやりがち。
SELECT
  id,
  name,
  description -- ここのカンマが抜けてる
  is_active
FROM t_users
ORDER BY id
;
非推奨や参照できないものをEclipseの保管機能とかで無理やり使う
非推奨ガン無視コーディング
ちゃんと調べてからつかってな……(レガシーコードの改修でありがち)
@Service
public class CreateUserService {
	@Autowired
	private UserMapper mapper;
	@Transactional
    @SuppressWarnings("deprecation") // コンパイラ警告を無視する
	public int create(CreateUserForm form) {
		User entity = new User();
		entity.setName(form.getName());
        // Springにおいて非推奨となっているクラスを無理やり使っている…
		StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        /**
        * 現在ベーシックなのはこっちを使うやり方だと思われる
        * BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        **/
		entity.setPassword(encoder.encode(form.getRawPassword()));
		return mapper.create(entity);
	}
}
コンパイルエラーを解消するために謎のclassやメソッドが爆誕する
確かに一時的にはコンパイルエラーは消えるんだけど…さ…
(テキストに沿ってコピペで実装したりしてるとたまになるっぽい)
public class Sample {
    // 引数でUserのBeanかなんかを参照したいが、まだUserクラス作られてないなどの場合はエラーになる
	public boolean isHoge(List<User> targetList) {
		boolean isHoge = false;
		for (User targetUser: targetList) {
			// 処理
		}
		return isHoge;
	}
    // Sampleクラス内に謎のクラスUserが爆誕(中身は何もないので当然その後の実装に支障をきたす)
	class User {
	}
}
インデントがスペースとタブ入り乱れ
一部の人間の心にこみ上げるものがあるので、タブかスペースどちらかに統一しましょう。
たいていのエディタにタブや空白文字の可視化モードがついてるので、パッと見ただけでわかるはず。
フォーマッタ入れてたらIDEによってはコード整形でちゃんと統一してくれそうな気はする。
// 表示モードでの表示例
␣␣␣␣// 空白文字4つ
^    // タブ1つ
なんかしらんが正規表現がうまくいってない
正規表現はものによってちょっとだけ違ったりするので、しょっちゅう調べてる気がします…
Javaで正規表現のチェックをするときは最初に簡単なif分岐を作って自分が思った通りの動きをしてくれるかチェックするというのを個人的には推奨してます。
下記は期待値を満たさないケースの正規表現です。(
どこに間違いがあるでしょうか。
public class RegTest {
    public static void main(String[] args) {
        // 10桁の数字チェックをしたい場合    
		String hoge = "1234567890";
		if (hoge.matches("^[0-9] {10}$")) {
			System.out.println("正解");
		} else {
			System.out.println("まちがい");
		}
	}
}
よく見るとhoge.matches("^[0-9] {10}$")の]と{の間に半角スペースが空いちゃってます。
大きなコードの中に紛れてると見つけづらいですが、このくらいのスコープであればすぐに問題が見つけられると思います。
筋肉コーディング
根性で結果を実現しようとして、期待値は満たすんだけどあんまりにもあんまりなコード。
ハードコーディングになりがち。
例として、特定の社員番号などを、特定の番号に変換したい場合が幾通りもあった場合のコーディングを記載しました。
public static String getNewEmployeeNo(String oldNo){
    String retString = "";
    if (oldNo.matches("^[0-9]{6}$")) {
        retString = "10" + oldNo;
    } else {
        switch(oldNo) {
            case "00000001":
                retString = "20000001";
                break;
            case "00000002":
                retString = "21000002";
                break;
            case "00000003":
                retString = "23000003";
                break;
            // 似たようなケース文が更に続く…
            default:
                retString = oldNo;
            }
    }
    return retString;
}
…DBのテーブルとかで管理しちゃったほうが早くね?ってことでcase文の部分はDBテーブルに変換情報を持たせる形に修正しました。
あまたあるクソコードの屍を超えて強くなれ
あるあるのやらかしで半日を無駄にしたとしても、そのクソコードの経験はきっとあなたを強くする…(はず)