Because We Love Happy Coding

フリーライターがPHPとかJavaとか勉強してます

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

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

Eclipseエディタのエラー表記が消えない

セーブしていない

基本。Eclipseのエラー表記は、保存されるタイミングで更新されるので、記述を直しても保存しないとマークが出たままになる。

何かのキャッシュが残ってしまっている

Eclipseでたまにある。ファイルを閉じて開くとエラーが消える。

「変数〜は一度も使われていません」

Eclipseの愛情を感じるエラーというかアラート。初心者向けのソースでは使わない変数でもお作法っぽい理由で変数作っていたりするので、けっこうこれが出てくる。

未完成ソースコード

未完成のソースコードで「エラーやアラートが消えません」と言ってくる事例。そりゃ未完成だからね。書き進めると消える種類のもの。

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

以下のケースが多い。

変数の宣言をしていない

基本。

宣言とスコープの問題

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

書き間違い

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

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

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

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

文字化け

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

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

文字コードの誤字

「uft8」とかその類型。

req側の指定とres側の指定両方が必要

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

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

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

JDBC

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」になる。

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

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

JSPサーブレット

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

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

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

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

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

404エラー

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

getParameterとgetAttributeの違い

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

EL式/Beansの形式

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

データベースアクセス専用のPHP設計

f:id:mogami74:20161208124847j:plain

自分のあれこれをデータベースに入れようと思っている。購入物とか、レストランの評価とかあれこれね。いっぱいいっぱい、作りたいデータベースがあるの。

とりあえずレストランについてはPHPで途中まで書いてみてそれなりには動いているんだけれど、ここから改修するのが面倒になってきた。この先、データテーブルが増えるたびに同じような作業をするのはめんどくさい。

というわけで、データベースアクセス専用のPHPを作ったらどうか、と考えた。しかしながら、いま一つ、どういう設計にしたらいいのか、いい考えが浮かばない。

Google先生に伺って、参考になりそうなサイトを見つけた。

blog.tojiru.net

blog.tojiru.net

まさにこれだ。用語がいくつか登場しているので、チェックしておいて後で調べることにする。

とりあえず、ユースケース的なまとまりごとにHogeDAOというクラスを作って、そこにDB操作を集約させることにした。各テーブルを体現するクラスも作成する。

たとえば、RestaurantsDAOクラスはRestaurantsTableクラスとVisitTableクラスを使いながらDBにアクセスする。(本当はStationTableとかMealTableもある)

こんなのもある。

d.hatena.ne.jp

  • Singleton

Singleton パターン - Wikipedia

Singleton パターン(シングルトン・パターン)とは、オブジェクト指向のコンピュータプログラムにおける、デザインパターンの1つである。(中略)Singleton パターンを用いると、そのクラスのインスタンスが1つしか生成されないことを保証することができる。

ふむー。成ル程。

Javaの勉強5

f:id:mogami74:20160225132733j:plain

ラッパークラス

基本データ型を参照型オブジェクトにしたもの。要するに、何でもオブジェクトにしちゃえば、メソッドも付けられて便利だよね、というオブジェクト至上主義ですよね(暴論)。

Autoboxingは、プリミティブ型をラッパークラスに変換する自動処理。

Generics

型を一般化したもの。これも「オブジェクトなら何でも処理しちゃうぜー」というオブジェクト至上主義ってことでいいよね。

こうなると、文字通り「何でもオブジェクト」だよなー。オブジェクト指向は偉大な発明だな。

Javaの勉強4

f:id:mogami74:20160306115355j:plain

クラスパス

-classpath.;c:¥classes セミコロンの意味は、パスの区切りということらしい。この場合、ドットとclassesと2つのパスを指定しているってこと。

例外

一般的例外と業務的例外。一般的例外は、Java上で用意されているもの。業務的例外は、主にユーザー定義例外。

チェック例外と非チェック例外。チェック例外は、外部システムとの境界のような、例外処理が必須になる部分。非チェック例外はシステム内部できちんと潰しておけば例外処理しなくてもいい部分。

Javaの検査例外は、呼び出し側の責任でない異常系 - Qiita

Javaの検査例外は、呼び出し側の責任でない異常系 - Qiita

throws は三単現のs。クラス名に付ける宣言。例外処理を呼び出し元に丸投げする宣言。
throw は命令文。例外をスローする、というヤツ。

実際の授業で「三単現」と「命令文」の話をしたら、同僚の先生に「今のできっとみんな覚えましたね」と誉められたな。

授業では例外処理のイメージを理解してもらうのが難しかったんだけど、「ソフトが強制終了してWindows が謝る」とか「異常終了の内容を送信しますか?ダイアログ」なんかを例外処理の例として挙げたらわかりやすかったかもしれない。

Collection API

Javaの近年のバージョンで追加された、集合を扱うAPIArrayListとか要素追加できて便利ね。

Javaの勉強3

f:id:mogami74:20170611084200j:plain

UML

コンポジション

以下の記事がわかりやすかった。

集約もコンポジションも「全体 - 部分」の関係。 集約は、モデリングする際には無視する(?)。関連と意味合いには変わらないので関連で表現できる。 コンポジションは、1つの部分インスタンスに対して最大1つの全体インスタンスで構成される。 最大1つなので、全体インスタンスの多重度は「0..1」もしくは「1」のどちらかになるはず。 部分インスタンスの譲渡や破棄などの責務を所有している全体インスタンスが担うことができる。 全体インスタンスと部分インスタンスのライフサイクルが完全一致しなくてもよくなった。 --via UMLの集約とコンポジションの違いについて - 目指せ!三流エンジニア

あと、こちらも役に立ちそう。

誤解しがちなモデリングの技:第1回:コンポジションにまつわるアレコレ | 豆蔵ソフト工学ラボ

誘導可能性

可視性と同じような意味で考えればいいのかな?

関連はデフォルトでは双方向性を持ちます。これは、関連から生成される2つのオブジェクトは両方相手を知っており、お互いにメッセージを交換し合うことを意味します。しかし、明らかに片方のオブジェクトからしかメッセージを送る必要がない場合に双方向性を持つとするならば、実装局面においてはプログラムコードに冗長性をもたらすことになります。また、モデルの意味上においても分かりづらさをもたらしてしまいます。このようなときには、関連の端に矢印を書くことで、関連の方向性を明確にします。図13では、明細から商品に向けて矢印を書くことで、明細は商品を知っているが、商品は明細を知らないという意味をモデルに付加しています。こうすることで、商品クラスが明細クラスから独立していることを強調することができます。このように関連の方向性をつけることを誘導可能性と呼びます。 --via 【改訂版】初歩のUML:第6回 「関連」の理解をさらに深める - ITmedia エンタープライズ

Javaの勉強2

f:id:mogami74:20170611082953j:plain

ポリモフィズム

似た機能のメソッド名を同じ名前に設定できることでアクセスの利便性を図ること。

抽象クラス、抽象メソッド

具体的な処理内容がないメソッドを抽象メソッドと呼ぶ。抽象メソッドを含むクラスを抽象クラスと呼ぶ。

抽象クラスでは、オブジェクトを生成できない。主にスーパークラスとして用いられる。

処理内容がないメソッドは、抽象メソッドと呼ばれ、ブロックを示す{}がなく、セミコロンのみ。

抽象クラスは、具象メソッドを持っていてもいいい。インターフェースは、具象メソッドを持っていてはダメ。

抽象クラスは単一継承のみ。インターフェースは多重継承が可能。

参照型のキャスト

暗黙のキャスト

サブクラスのオブジェクトをスーパークラス型の参照変数に代入できる。これには明示的なキャストは不要。

基本的にはキャストした先(スーパークラス型)のメソッドだけしか利用できないので、サブクラスのみに設定されたメソッドは使用できなくなる。

ただし、オーバーライドされたメソッドはキャストした状態から使用できる。これはたとえば、スーパークラスとサブクラスでポリモフィズム的観点から同じ用途のメソッドを用意しているようなパターンになるはず。

ダウンキャスト

スーパークラスの参照変数をサブクラスの参照変数に代入する際は明示的にキャストを行う。これをダウンキャストと呼ぶ。

シグニチャ

シグニチャ」はメソッド名、戻り値の型、引数の型と個数を組み合わせたもの、と勉強中のテキストにはあるんだけれど、主にメソッド名と引数の型リストを指すことが多いみたい。

つまりオーバーロードとは「シグニチャが異なる」メソッドを記述する行為になる、かな。

逆に言うとオーバーロードされたメソッドを呼び出す場合は「シグニチャが一致する」ものが選ばれて実行される、ということになる、はず。これなら「signature」という単語の意味とも合致するし。

インターフェース

「インターフェース」として複数の抽象メソッドを定義しておくことができる。

この2つ(だけ)を行う。実行内容は定義しない。

1つのクラスが複数のインターフェースを多重実装することもできる。

実装クラスでは、インターフェースに存在するすべての抽象メソッドを実装/オーバーライドする必要がある。もし実装していないメソッドがある場合はabstract宣言して抽象クラスにならなければならない。

参考記事

Java 入門 | インタフェース

Java SE 8 でのメソッド継承のルール - 映画は中劇

Javaの勉強1

f:id:mogami74:20170611082215j:plain

領域

これについては私は学校で教わらなかったので、よく勉強しておかないといけない。

領域図

これも学校では描かなかった。変数設計ってことだよね……。

自分でPHPを描いた時には、スーパーグローバル変数だけとりあえず変数一覧を作成していた。でないと、あちこちで設定した変数名が同じだったり書き間違えたりで悲惨なことになるので。

「入出力領域」と「作業領域」の具体例がピンと来ないけど、まぁおいおい。

個別データ記号

「順次アクセス」って何だっけ。

https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9ja.wikipedia.org

ああ、ランダムアクセスの逆ね。直接アクセスって日本語では言ってるのか。

制御移行

他のプログラムの呼び出し……ね。成ル程。

ANDゲート

見慣れない記号があったので調べてみた。 https://ja.wikipedia.org/wiki/AND%E3%82%B2%E3%83%BC%E3%83%88ja.wikipedia.org ふむ。遅延と同じ意味ってのは、どうも電子回路の流れらしいから、その辺が理解できてないとピンと来ないな。