/【初心者向けトレーニング】Javaの演習問題:構文編2017.03.02【初心者向けトレーニング】Javaの演習問題:構文編Java演習問題TweetPocketこのページではJavaの演習問題をいくつか用意した。Java特有の文法の知識があれば解けるような演習問題たちだ。Javaを勉強中の方はチャレンジしてみてほしい。アルゴリズムを考えて解く演習問題は下記に用意している。こちらも参考にしてほしい。問題で定められた規則に従い、正しく入力されるものとし、入力ミスなどは考慮しなくてよい。問題1(起動パラメータ)起動パラメータに指定された引数をすべて表示するプログラムを作成しなさい最初に、引数の個数を出力する。引数は一つ以上指定されるものとする。12345出力例:引数は3個指定されています。1番目の引数は「ABC」です。2番目の引数は「あいうえお」です。3番目の引数は「12345」です。1234引数は3個指定されています。1番目の引数は「ABC」です。2番目の引数は「あいうえお」です。3番目の引数は「12345」です。問題2(例外)プログラム中で、以下の例外を発生させる処理を記述し、その例外の詳細情報は出力しなさい。Null参照によるNullPointerException配列の範囲外参照によるArrayIndexOutOfBoundsException互換性の無いオブジェクト型の変換によるClassCastExceptionただし、プログラムは例外による異常終了はせず、正常に終了すること。Main.main(Main.java:21)問題3(static、ジェネリクス、アノテーション)起動パラメータに指定された引数配列に対し、List型の変数に格納するList型の変数に格納された値を表示するを行うプログラムを作成しなさい。12345123ABCあいうえお12345いかがだっただろうか?以下は、演習問題の回答になるので、解き終わってから確認してほしい。"個指定されています。"個指定されています。");}}}入力パラメータを数値に変換する。文字列を数値に変換する際、文字列が「-N」の形式の場合は、負の値として変換される。javaプログラムを実行する際の基本的な問題だ。コマンドラインからjavaプログラムを起動する事は、実はあまり多くは無いのだが、基礎知識として押さえておこう。ポイントとしてはmain()メソッドの引数String[]には、コマンドライン引数が渡される。引数String[]には、プログラムに渡されるコマンドライン引数のみが格納され、コマンドラインオプションや実行クラス名は含まれない。この2つ目の「コマンドラインオプションや実行クラス名は含まれない」というところに「なんでわざわざそんなことを」と思われたかも知れない。実は、プログラム言語によっては、起動引数の1番目に実行プログラム名が格納され、引数は2番目以降となるものがある。引数だけが渡されることが当たり前ではないので注意してもらいたい。ex){ex.printStackTrace();}}}javaでは、try/catchという構文を利用して、例外の捕捉(ハンドリング)を行う。プログラム中に例外(Exception)が発生した際に、適切な処理継続(安全な終了処理を含む)のために、「例外の捕捉」を行う必要がある。NullPointerExceptionの発生要因は、Nullオブジェクトに対するメソッドの呼び出しだ。1では、変数nameは宣言後にnullで初期化され、その後実体の代入処理が無くsubstringメソッドが呼び出されている為にNullPointerExceptionが発生する。この問題を回避するためには、宣言した変数がどのタイミングで値(オブジェクト)が代入されるのかを意識しながら全体の処理を記述する必要がある。ArrayIndexOutOfBoundsExceptionの発生要因は、配列の範囲外の要素へのアクセスだ。10個しか要素を用意していない配列なのに、11番目(添え字は10)の要素に代入したり参照したりすると発生する。2では添え字「2」の要素(1番目の要素)に対して代入を行っているが、配列valuesを宣言した際に定義した要素数は「2」であり、添え字の最大番号は「1」(「0」から始まって2つ目は「1」)であり、添え字「2」に該当する要素は存在しないため、ArrayIndexOutOfBoundsExceptionが発生する。この問題を回避するためには、配列の最大数(添え字の最大番号)は幾つになるのかを意識しながら全体の処理を記述する必要がある。配列の場合はlengthプロパティを参集するなどして、要素数の変化に耐えうる処理を記述するよう心掛けると良いだろう。ClassCastExceptionの発生要因は、互換性のオブジェクトの型変換(キャスト)だ。3では、Object型として宣言された変数に、String型のオブジェクトが代入されたものを、互換性の無いInteger型変換しようとしているためにClassCastExceptionが発生する。Object型はその名のとおりオブジェクト型の変数の値であればどのようなものでも代入可能で、String型のオブジェクトを代入する事も、Integer型にキャストする事も可能なため、コンパイルエラーにならないが、実行時に実際に格納されている型がString型のものをInteger型に変換するという事は、互換性の無い型同士での変換のため、Exceptionが発生してしまう。この問題を回避するためには、そのオブジェクトが実態としてどんな型のオブジェクトを保持しているのかを意識しながら全体の処理を記述する必要がある。ArrayListやHashMapのようなObject型を格納するオブジェクトには、ジェネリクスという型指定の考え方がある。;というように、変数の宣言時に扱う型を限定してしまうのだ。これにより、実行時にClassCastExceptionが発生する可能性は低下するだろう。ここで紹介した3つのExceptionは、どれもよく見かけるものなのだが、発生原因の多くは考慮不足によるものだ。3つのExceptionはRuntimeExceptionの派生で、本来は発生しないものである。Exceptionには大きく分けて起こりうることが予想できるException起こりうることが予想できず、多くの場合はプログラム中の問題であるの2つに分類され、後者はRuntimeExceptionを指している。前者は、ファイルアクセス処理において、プログラムの実行時にファイルが見つからずに「IOException」が発生するケースなどが良い例だ。プログラムとしては、処理を行うべきファイルが必ず存在する前提でプログラムを実行するのだが、プログラム外の問題でもあるので、「起こりうることが予想できるException」としてtry/catch文を利用して「Exceptionが発生したときの対処方法」を事前に明確にしておくべきだろう。RuntimeExceptionでは無い例外の場合、必ずハンドリング処理を実装しなければならないようにjavaの言語仕様として定められている。これに対し、RuntimeExceptionはあくまでも実行時の例外であり、事前に予測のできるものではない。プログラムの実行パターンを不足なく確認できれば、RuntimeExceptionの発生を抑えることは可能だ。プログラム経験の浅いうちはRuntimeExceptionが多発するが、習熟度が上がるにつれてあまり見かけなくなるものでもある。2つのExceptionの違いを最初から理解するのは難しいかも知れないが、少しずつ慣れていこう。params){System.out.println(param);}}}この問題は、何のひねりもない陳腐な問題と思われた方もいるだろう。Javaにおけるいくつかの重要な要素を含んでいるので、解説をよく読んで理解を含めて欲しい。staticプログラム中の以下の記述に注目してもらいたい。Arrays.asList(args);これはString配列をList型に変換する処理を行う、Java標準の機能を使用したものだ。ここでは、「Arrays」というクラスの「asList()」というメソッドを呼び出しているが、Arraysは変数では無く、クラス名を指している。このように、クラスの実体を生成する事無く、そのまま使用できるメソッドの事を「staticメソッド」と呼ぶ。staticメソッドはJava標準機能でもいくつか用意されており、いずれも多くのプログラムで利用されるような汎用的な機能だ。ジェネリクス本来、リスト型の変数には、StringのみならずIntegerやDateなど、どのような型のオブジェクトも格納可能だ。取り出す側のプログラムを記述する立場から見れば、どんな型のオブジェクトが入っているのかが分からないという曖昧さが生まれ、取り出した値の取り扱いに困ってしまう。これを解決したのが「ジェネリクス」という考え方だ。Listのように、どんなクラスのオブジェクトでも扱えるクラスであっても、変数の宣言時にその用途を限定することで、プログラムの曖昧さを抑制するものだ。ジェネリクスの考え方を適用せずにこのプログラムを記述すると、以下のようになる。(String)params.get(idx);System.out.println(param);}}}しかし、EclipseなどのIDEを使用してコンパイルを行うと、警告が出ていることが分かるだろう。実際にこのプログラムを作成し、実行すると正しく動作する。これはList変数の宣言時に型を明示していないために出されている警告だ。最初の解答例のように、拡張for記述を使用することも出来ず、コンパイルエラーとなる。params){System.out.println(param);}これも、配列要素のオブジェクトの型が明示されていないからだ。params){System.out.println(param);}この場合、paramをStringとして使用するのであればと記述するしかない。(String)paramと、キャスト(強制的な型変換)を行う必要がある。アノテーション上記のジェネリクスのケースで、どうしても警告が出て気になる場合には、警告の抑制を行うことができる。(String)params.get(idx);System.out.println(param);}}}このように、@SuppressWarnings("rawtypes")という記述を追加するだけで、型定義の曖昧さに関する警告は抑制される。このように「@」で始まる記述を「アノテーション」と呼ぶ。アノテーションは「注釈」と呼ばれ、様々なものがある。コメント的な意味を表すものや、使ってほしくないメソッドに対する警告的なものなど様々だ。EEでは、サーバーサイドプログラムの実行定義に関する命令を、アノテーションを使用して記述する。このように、様々な目的でアノテーションが使用されているが、使う場面は熟慮すべきである。先の@SuppressWarnings("rawtypes")のような記述は、極力利用すべきでは無い。ジェネリクスによる型の明示は、プログラムの品質を高めるために考案されたものであるのに対し、@SuppressWarningsを記述することで、その警告を隠ぺいしてしまうことになるからだ。利用する場面としては、旧バージョンのJava(1.4以前)で作成した共通処理のソースコードを、そのまま利用して新バージョンのJava向けの開発に利用するようなケースだろうか。1.4以前のJavaでは、ジェネリクスというものが存在しなかったため、型の明示はせずにあいまいなまま使用していた。そのプログラムを、そのまま改変せずに新バージョンで使用すると、至る所で警告が発せられることになるだろう。いって、警告個所をジェネリクス記述に訂正する事で、不要なミスを呼び起こす危険も考えられる。そんな場合であれば@SuppressWarningsを用いて、警告を隠ぺいしても良いだろう。いずれにしても、アノテーションは適した場面で活用すれば、プログラム作成の簡素化や品質の向上につながるものだ。まとめこのページではJava特有の文法的な問題についてまとめてきた。解答だけ見ずに、実際にトライをしてみて、スキルを上げていただければと思う。TweetPocketこのページの続きや関連ページは下記から一覧で確認できる。・「プログラマーとして転職をしたい!」という方はリナックスアカデミーの資料を見てみてください。短期間で未経験からエンジニアになることができるスクールとして15年間選ばれ続けてきた理由やノウハウが載った資料です。エンジニアの入り口に立つために必要な勉強や技術の最新動向、本当に使えるIT資格、学習に役立つ国からの奨励金などの情報が詰まっています。無料で2,3日中にお手元にお届けします。資料を見てみるSNSでもご購読できます。IT研修専門企業のリナックスアカデミーです。】エンジニアの入り口に立つために役立つようなコンテンツを日々ご提供していきます。講師や代表やスタッフ陣が毎日楽しく書いています。ご質問・ご指摘等はぜひコメントください。*メールアドレス(公開はされません。*次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。必要な勉強や技術の最新動向、本当に使えるIT資格、学習に役立つ国からの奨励金などの情報を無料でお届け資料を見てみる。