目次
型≒オブジェクトの構造。「静的~」は構造をコンパイル時にチェックする。「動的~」は構造を実行時にチェックする。
こんにちは。技術チームの岩谷です。本連載ではオブジェクト指向プログラミング(OOP)をおさらいする連載を書かせていただいています。今回は第五回として「静的型付けと動的型付け」について説明します。
「静的型付け・動的型付け」は両者ともプログラミング言語の種類です。「型付け」とはプログラムがオブジェクトの構造(≒変数の型)に関する整合性を検査する機能の事です。例えば数値を入れるオブジェクトに”岩谷”のような文字列を入れようとした場合、整合性が取れていないのでエラーが発生します。これに関して、
- 「静的な型付けのプログラミング言語」は、この整合性を「コンパイル時」に検査します
- 「動的な型付けのプログラミング言語」は、この整合性を「プログラム実行時」に検査します
みなさんがご存知のプログラミング言語だと、
- Java、C、C#、VB.netなどは「静的な型付け」
- JavaScript、Python、Rubyなどは「動的な型付け」
という種類に分かれています。この種類分けは言語を作った創造者が決めたことであり、言語が生まれ持った性質です。
先日、とある方から「JSONデータの取り扱いはJavaScriptだと簡単なのに、Javaだと面倒くさいと感じているのですが、JavaでJSONデータを取り扱う便利な方法はありませんか?」という質問をいただきました。この質問については「Java API for JSON ProcessingやJackson、GoogleさんのGSONなどいろいろなJSON操作ライブラリがありますよ。また、Java9に搭載予定のLight-Weight JSON APIもすごく期待できます」とお答えさせていただきました。
ただその後、「JavaScriptだと簡単なのに、Javaだと面倒くさい」というそもそもの理由は、「ライブラリの有無」ではなく「JavaScriptが動的な型付けのプログラミング言語であるのに対して、Javaが静的な型付けのプログラミング言語」である事なのだと、後から気づいてしまったので、今回この場を借りて説明をさせてください。
データとプログラムソースを見ながら両者を比較
では、「静的型付けと動的型付け」のプログラム的な違いを「JSONデータの取得処理」を例に説明します。
- サンプルデータとしてJSONデータを用意しました。
- 静的型付けのサンプルソースとしてJavaのソースを用意しました。
- 動的型付けのサンプルソースとしてJavaScriptのソースを用意しました。
サンプルデータ
以下のデータを入力対象とします。データの内容は「プロ野球歴代ホームラン数の順位」です。出展元は「日本プロ野球機構オフィシャルサイト・歴代最高記録 本塁打 【通算記録】」です。
1 2 3 4 5 6 7 |
[ {"順位":1,"氏名":"王貞治","本数":868} , {"順位":2,"氏名":"野村克也","本数":657} , {"順位":3,"氏名":"門田博光","本数":567} ] |
以下2つのプログラムはこのデータを読み取ってコンソールに内容を出力するプログラムです。
静的型付けの例=Javaのサンプルソース
1 2 3 4 5 6 7 8 9 |
//Javaのソース(静的型付け) String strData = 上記のJSON文字列 List<Map<String,Object>> list1 = (new com.google.gson.Gson()).fromJson(strData, List.class); for(int i = 0; i < list1.size(); i++) { System.out.println("順位は" + list1.get(i).get("順位")); System.out.println("氏名は" + list1.get(i).get("氏名")); System.out.println("本数は" + list1.get(i).get("本数")); } |
なお、上記の処理におけるJSONデータの取得処理にはGoogleのGSONライブラリ(com.google.gson.Gson)を使用しています。
動的型付けの例=JavaScriptのサンプルソース
1 2 3 4 5 6 7 8 9 |
//JavaScriptのソース(動的型付け) var strData = 上記のJSON文字列 var list1 = JSON.parse(strData); for (var i = 0; i < list1.length; i++) { console.log("順位は" + list1[i].順位); console.log("氏名は" + list1[i].氏名); console.log("本数は" + list1[i].本数); } |
両者の違いは「オブジェクトの定義」に現れる。
上記2言語の処理の違いは3行目に顕著です。すなわち、JSONを格納するオブジェクト「list1」の定義を、
- 静的型付け言語であるJavaは「List<Map<String,Object>> list1」と、JSON内部の型までも予め定義してるのに対して、
- 動的型付け言語であるJavaScriptは「var list1」と、JSON内部の型には言及せずに定義している
という違いです。オブジェクト「list1」の構造整合性を、Javaは定義するとき=コンパイル時に検査しているのに対して、JavaScriptはオブジェクト内部を参照するとき=実行時に検査しているのです。
どちらが好いかは一長一短、表裏一体。システムの性格に応じて使い分けよう。
今回は「静的型付け・動的型付け」について具体的なサンプルプログラムを見ながら特徴を説明しました。しかしここまでの説明ではこの両者の優劣について説明していません。それはこの違いが優劣ではなく表裏一体の差異であるからなのです。
静的型付け言語では、オブジェクトの構造検査をコンパイル時=プログラムの製造段階で行うことが可能です。より早期での検査が可能であるがゆえにシステム全体の堅牢性は向上します。この特性ゆえに「システムを構成するプログラムの数が多い大規模システムを安全に構築することに向いている」と言われます。
対して動的型付け言語では、オブジェクトの構造(=型)をコンパイル時には検査しないことで型の定義を省略した「シンプルなコード」「自由度の高いコード」を記述することが可能です。実際、上記2つのソースを見比べるとJavaScriptのソースのほうがコード量が少ないことがお分かりいただけると思います。本記事冒頭の「JSON処理が、JavaScriptだと簡単なのに、Javaだと面倒くさい」とおっしゃった方の感覚もこの記述量の違いに起因するところが大きいのでしょう。この特性ゆえに「プログラムの開発速度を求めるシステムの構築に向いている」と言われます。
我々がシステムを構築していく際には、これらOOP言語の持つ特性を加味して最適な開発環境を選択することも大切です。
【本連載について】
- OOPと非OOPの違い|オブジェクト指向プログラミング(OOP)をおさらいしよう(1)
- 継承によってコードを再利用する|オブジェクト指向プログラミング(OOP)をおさらいしよう(2)
- インターフェースとは?~継承とは役割が違う~|オブジェクト指向プログラミング(OOP)をおさらいしよう(3)
- カプセル化とは?~安全なシステムを作る為の配慮~|オブジェクト指向プログラミング(OOP)をおさらいしよう(4)
- 静的型付けと動的型付け~JavaとJavaScriptのJSON処理を比較~|オブジェクト指向プログラミング(OOP)をおさらいしよう(5)