この記事は?
Oracle Java SE8 Silverの試験対策を行った際に、ミスリードや単純ミスで間違ってしまった問題のパターンをリストアップしました。
配列
int[] nums;
nums = {1, 0}; //コンパイル・実行成功
nums = {1.0}; //コンパイルエラー
三行目をピリオドとカンマを見間違えてしまったパターンです。
カンマの後はスペースが入るので気を付ければ見間違えない…と思います。
Stringのメソッド呼び出し
String hoge = " ho ge ";
hoge.trim();
System.out.print(hoge); //「 ho ge 」が出力される
Stringのメソッド(特にtrim,replaceなど変換)を呼び出してはいるけれども変数に再代入していないパターンです。
上記例は他の処理を削っていますが、他の文字列操作に埋もれてしまうと意外と見落としてしまいます。
String型でなくStringBuilder型をreturn
public String hoge(){
StringBuilder huga = new StringBuilder("huga");
return huga.append(" huga");
}
文字列操作を行った後、脳内で勝手にStringBuilderをStringにキャストしてしまうパターンです。
選択肢にも複数紛れているので、StringBuilderを使う場合は特に戻り値の型に気をつけましょう。
ローカル変数名とフィールド名が一致
class Hoge {
int a;
void huga() {
int a;
...
System.out.println(a);
}
}
IDEだと色分けが出来るため分かりやすいですが、単色だとローカル変数の存在を忘れがちです。
フィールドを参照するならthisが付くので分かりやすいのですが…
継承の継承(メソッドの実装)
abstract class A {
abstract void hoge();
}
abstract class B extends A {
void huga() {};
}
class C extends B {
}
この場合、クラスCが原因でコンパイルエラーとなります。
原因はクラスAのメソッドhogeを実装していないことです。
クラスBはクラスAを継承してはいますが、抽象クラスのためhoge()を実装せずともエラーにはなりませんが、
クラスCは具象クラスのため、実装が必要となります。
明示的にコンストラクタを定義している場合
上記の場合、引数無しのコンストラクタは自動生成されません。
しれっと呼び出されてると見逃しがちですが、コンパイルエラーとなります。
付録:学習するまで知らなかったこと
toStringによる自動変換
文字列結合の時とかにtoStringが呼ばれてStringに暗黙的に変換されます。
明示的に変換することが多く、暗黙変換に頼る機会がそこまでなかったと感じています。
(StringBuilder型とString型を+演算子で結合する、なんて問題も出てきますが、役立つ日は来るんでしょうか?)
ArrayListのadd(int index, object obj)
挿入位置を指定しなければならないシチュエーションがあまりなく、addメソッドで指定可能であることを知りませんでした。
メソッドを逐一暗記するよりはリファレンスの読み方を身に付けた方が実用的ではとは思います。
meinメソッドにthrowsを記述しても良い
内部で処理しきらない方が良いパターンもあるのでしょうか?
試験対策を実施した所感
今まで触れてこなかったパターンを多く学ぶことが出来ましたが、実務上活用出来るかというと少し微妙なところではあります。
コンパイルを通せて動作はするけれどもアンチパターンである、といった題が多く、そういったパターンを初学者が「コンパイル・実行可能である」と学習してしまうのは問題があるのではと感じます。
そのため、本試験は言語の理解を深めることが主であり、良いプログラムを書けるようになることが目的ではないと理解した上で対策に取り組むべきだと考えます。
それとIDEとリファレンスの偉大さを痛感いたしました。