Because We Love Happy Coding

フリーライターからエンジニア × 講師。発信力だけあり余ってる感じ

Java初学者がひっかかっていたところまとめ

今日もまたコーディング。だって僕らはHappy Codingが大好きだから。

1ヶ月ほど初学者に教えた際、ひっかかっていたところをまとめた。何かの参考に。

文字列+文字列

一定の確率で、文字列+文字列 が 文字列であることを理解していない受講生に遭遇する。変数を間に挟んでも混乱する。

コンパイルエラー unsolved compilation problem / reached end of file while parsing } / 構文解析中にファイルの終わりに移りました

{}の付け忘れなどが多い。字下げを指導する。

全角文字

最初のうちはよく全角空白を入力してしまい、コンパイルエラーを起こす。

文字¥uefffは不正

「〜を変数に解決できません」

以下のケースが多い。

変数の宣言をしていない

基本。

宣言とスコープの問題

これが割と多い。
「宣言した変数はブロック内で有効」ということがまだ飲み込めずエラーになっている。
あるいは逆に上位のブロックで宣言したために、破棄されるべきデータが破棄されず残ってしまい、想定外の挙動をする。

書き間違い

メソッド名に()を付け忘れるなどで変数名と見なされてしまい「〜を変数に解決できません」になる。

「型名を解決できません」

自分で作成したクラスの場合は打ち間違い。

(自分で作成していない)クラス名が与えられている場合は、import忘れが多い。

文字化け

いくつかのパターンがある

文字コード指定がおかしい

文字コードの誤字

「uft8」とかその類型。

サーブレット)req側の指定とres側の指定両方が必要

サーブレットの場合、RequestとResponse両方に文字コード指定が必要。

req.setCharacterEncoding("UTF-8");
res.setContentType("text/html; charset=UTF-8")

オブジェクトを直接System.out.printしようとしている

データを保持するEntityオブジェクトをそのまま表示しようとして文字化けする。

JDBC

JDBC URL

jdbc:mysql://localhost:3306/db_name
  • localhost……ホスト名
  • 3306……MySQL標準のポート番号
  • db_name……使用するデータベースの名前を入れる

duplicate PRIMARY KEY

jdbcSQLのINSERT文を実行する際に、「既に存在する主キー」を追加しようとすること。IDの重複など。
例文の通りにINSERT文を打ち込んで、2回(以上)実行しようとするとこれが出る。

引数間違いによるSQLException

サーバー名などの打ち間違いが多い。「locahost」などサラッと書いてあると意外と見つけづらい。

INパラメータ指定

PreparedStatementのINパラメータを指定する際に順番を間違えている。

suitable driver not found

DriverManager.getConnection(url,user,password)で「suitable driver not found」と出る。

getConnection()の第一引数のurlを打ち間違えている

jdbc:」と書くべきところを「jbdc:」と打ち間違えたりすると、「driver not found」になる。

環境設定ミス。クラスパスが何かの原因で通っていない。

これはしんどい。なかなか気づかない。

Class.forNameを使って読み込むための備忘録。

Class.forName("com.mysql.jdbc.Driver");
con = DriverManager....

JSPサーブレット

「formのname属性」「key」「変数名」の混乱

往々にしてベテランは後で見て追いやすいように(サンプルコードも)同じkey名を使い回す傾向がある。慣れた人は文脈を見れば「これが変数名」「これが属性名」などすぐわかるのだけれど、初学者にはどれがどれに対応しているのかわかりづらい。

サンプルコードでユーザーなどの「名前」をデータとして持つ場合が最悪でこんな感じになる。

  • HTML/JSPファイル: formタグのname属性に氏名を入力させ"name"のキーを持たせる
  • httpリクエスト: 格納されているkeyが"name"で値が"山田"
  • サーブレット: request.getParameter("name")で取り出した値を入れる変数名がname

name の name が nameである、みたいなことになり、ここを丁寧に説明しないとしんどい。

f:id:mogami74:20180520114745j:plain

f:id:mogami74:20180520114749j:plain

404エラー

JavaリソースとHTML/JSPのパスの違い。
Javaリソースはアノテーション(またはweb.xml)でパスを指定するため、プロジェクト名の直下がほとんど。HTMLやJSPなどはディレクトリ階層を正しく指定する必要がある。

ローカルファイル参照

HTMLからサーブレットを呼び出す際に、Cドライブ上のHTMLを開いてサーブレットを呼んでいるケースがある。これだとwebコンテナが起動していないのでサーブレットは動作しない。

アドレスバーを見るクセをつけさせた方が良い。

getParameterとgetAttributeの違い

formから受け取る時は getParameter() 。
setAttribute() したものを受け取るときは getAttribute() 。
getAttribute() のキャスト忘れ/キャストミスもある。

EL式/Beansの形式

${sessionScope.key.member} のようにドット記法でつなぐのを忘れて、 ${sessionScope.key} または ${sessionScope.member} のように書いてしまうことが多い。

JSP)宣言タグを使うのと、スクリプトレット内で宣言するのとどう違うのか?

宣言タグ内で宣言する

JSPがクラスに変換される際、メンバ変数となる。JSPインスタンスを複数ユーザーで使い回すので、複数ユーザーで値が共有される可能性があることに注意。

スクリプトレット内での宣言

JSPがクラスに変換される際、メソッドのローカル変数になる。httpリクエストが来るたびに初期化される。

JSTL core

出力タグ c:out value=${EL式}

値がnullの場合に初期値を出力する機能があるため、nullセーフ。
エスケープ処理する機能もある。