「Java」の版間の差分
削除された内容 追加された内容
→Javaプラットフォーム: 字面を変えただけで何も解決していません。剥がすなら出典を付けてください。 タグ: 2017年版ソースエディター |
Goldensundown2 (会話 | 投稿記録) スレッド |
||
(同じ利用者による、間の13版が非表示) | |||
29行目:
}}
{{プログラミング言語}}
'''Java'''(ジャバ)は、狭義では[[プログラミング言語]]のJavaを指し、広義ではJava言語を中心にした[[プラットフォーム (コンピューティング)|コンピューティング・プラットフォーム]]を意味する<ref>{{Cite web|url=https://www.java.com/en/download/faq/whatis_java.xml |title=What is Java and why do I need it? |language=en |accessdate=2019-02-04}}</ref>。後者はJavaプラットフォームと呼ばれ
Java
Javaは、1995年に[[サン・マイクロシステムズ]]によって公開された。2010年にサンは[[オラクル (企業)|オラクル]]に吸収合併され、Javaの各種権利もオラクルに移行した。おおよそ数年おきに言語仕様の改訂が重ねられており、2019年
==
Javaは5つの
=== Javaの理念 ===▼
▲Javaは5つの理念に基づいて開発された<ref>{{Cite web|url=https://www.oracle.com/technetwork/java/intro-141325.html |title=The Java Language Environment |accessdate=2019-04-24}}</ref>。
# シンプルで、[[オブジェクト指向プログラミング|オブジェクト指向]]で、見慣れたものにする(''simple, object-oriented, and familiar'')
# 堅牢で
#[[プラットフォーム非依存]]で、[[移植 (ソフトウェア)|移植]]を容易にする(''architecture-neutral and portable'')
# 高いパフォーマンスで動作する(''to execute with high performance'')
#[[インタプリタ|インタプリタ式]]で、[[
Javaの言語仕様は、[[C++]]のそれから堅牢性を損ねる部分を取り除いたものと考える事が出来る。[[ポインタ (プログラミング)|ポインタ]]、直アドレスの[[インスタンス]]と[[配列]]、[[テンプレート (プログラミング)|テンプレート]]、[[演算子オーバーロード]]、[[goto文]]などが
'''
: Javaの全[[インスタンス]]は実体データを指す参照値(アドレス)に統一されている。[[配列]]は特殊なインスタンスとなっており、[[文字列]]も自動的にインスタンスとなった。これによって特に[[引数]]と返値の受け渡しに混乱が無くなり堅牢性も増した。非参照インスタンスを自動解放する[[ガベージコレクタ]]が導入されたので、メモリ管理の不要に伴うプログラムの簡素化と堅牢さも促進された。なお、8bitから64bitまでの数値を収納するデータは[[変数 (プログラミング)|直アドレス変数]]となっているが、そのアドレスを扱う事は出来ない。
56 ⟶ 52行目:
'''型定義と関数の在り方'''
:
'''オブジェクト指向の在り方'''
: オブジェクト指向は[[C++]]と同様の[[クラス (コンピュータ)|クラス]]のメカニズムに基づく仕様から[[多重継承]]が取り除かれ、無名クラスの構文が追加されている。後者は[[プロトタイプベース]]オブジェクトの取り扱いに近い利便性を実現した。[[カプセル化]]はソースコード単位がデフォルトの緩やかなもので利便性が優先されている。Javaの[[多態性]]の中心は[[仮想関数]]であり、その集合体である''interface''構文が専門に用意されている。''interfaceは[[継承]]と区別されて多重に[[派生型|実装]]できる。''また堅牢性を重視しながらも動的な[[型システム|型比較]]と[[型変換|型キャスト]]と[[リフレクション (情報工学)|リフレクション]]が備えられており、動的な多態性の実現が優先されている。上述二点の多態性の背景には[[分散コンピューティング]]の重視があり、その実現をサポートする[[ネットワーク・コンピューティング|ネットワーク]]機能と[[Java Remote Method Invocation|リモートメソッド]]
'''
: Javaでは[[
'''堅牢性から利便性へ'''
: Javaの予約語は少なくAPIは膨大であり、シンプルで応用性に富んだ言語仕様と見る事が出来る。基礎部分を簡素化して残りをアドオン的にする設計は、Javaの主眼である[[マルチプラットフォーム|マルチプラットフォーム性]]を実現する為でもあった。加えてJava仮想マシン上でのプログラム実行は基礎レベルからの堅牢性とセキュリティを実現した。公開初期と比べたJavaの方向性は大きく変化している。[[ポリモーフィズム|動的多態性]]、[[分散コンピューティング|分散処理]]、[[並行処理]]、[[ジェネリックプログラミング|総称型構文]]、[[関数型プログラミング|関数型構文]]の拡張ないし追加が示すものは柔軟性(''flexible'')と利便性(''utility'')の追求であり、結果的に堅牢性(''robust'')を旨としたJavaの哲学に優越した。
=== オブジェクト指向 ===
126 ⟶ 128行目:
しかし、Javaのプラットフォーム非依存性は、[[サーバ]]側や[[組み込みシステム]]のアプリケーションに関しては成功を収めている。サーバ側 ([[Java Platform, Enterprise Edition|Java EE]]) では、Java の[[Java Servlet|サーブレット]]、[[Webサービス]]、[[Enterprise JavaBeans|EJB]] (Enterprise JavaBeans) などの技術が広く使われている。組み込みシステムの分野においても、組み込みシステム向けの Java環境 ([[Java Platform, Micro Edition|Java ME]]) を使った[[OSGi]]を基にした開発が広く行われている。
===
Javaではその前身であるGreenOS用言語およびOakの時代にあたる家電機器の組込システムへの普及を目指していた極めて初期の段階から、スレッド式(''threaded'')を基底要素にして設計されていた。組込システム開発では主に2~4タスクによる並行処理が要望される状況が頻出しており、大抵はシングルタスクでも実装可能なコルーチンによる交互切り替えフローで対応される事が多かった。家電機器の高機能化に伴うマルチタスク環境のニーズ増加を予測したサン社のプロジェクトチームは、その組み込み分野におけるシェア独占を目指してマルチスレッド機能の標準配備を、プログラミング言語と仮想マシン設計における重要課題としていた。初期バージョンにおけるJavaのスレッドは、仮想マシン実行上のユーザー空間で走行される純粋なユーザースレッドとして実装された。一台のJava仮想マシンの実行は一つのプロセスとなり、Javaのプロセスは始めから複数スレッド(糸)の寄り合わせとして設計されていた。この高度なネイティブスレッド・エミュレート技術は注目を集め、その開発チームの名に因んだグリーンスレッドという名称を確立し、ランタイムライブラリ及び仮想マシン上で走行されるマルチスレッドの代名詞となった。グリーンスレッドは公開初期においては、例えばLinuxのネイティブスレッドよりもやや軽量なパフォーマンスを発揮した。組み込みシステム向けのJava仮想マシンでは基本的にこのグリーンスレッドが標準仕様となり続けている。しかし、パソコンやサーバーマシン用の各OSの間でマルチコアCPUの特性を活かしたより軽量なネイティブスレッドが一般的になると、グリーンスレッドのパフォーマンスは明確に見劣りするようになった。やむなく開発チームはグリーンスレッドを順次廃止し、OSが提供するネイティブスレッド上で走行させるように設計変更した。特に並行処理同期=排他制御を多用するJavaプログラムにおいては、この時点からプラットフォーム非依存性に対する問題が生じるようになったと言われる。
Javaの同期(''synchronization'')は、
=== ガベージコレクション ===
151 ⟶ 155行目:
ガベージコレクションの機構は、Java仮想マシンに組み込まれており、開発者からは、事実上隠蔽されている。開発者は、場合にもよるが、ガベージコレクションがいつ起こるか意識しなくて良い。というのも多くの場合、ガベージコレクションの実行は、プログラマが自分で書いたコードによって明示的に起こる何らかの挙動と、必ずしも関連しているわけではないからである。
=== ネットワーク
Javaでは充実した[[ライブラリ]]により、[[コンピュータネットワーク]]を活用するソフトウェアを、効率良く開発できる。Javaはその初期のバージョンから、[[インターネット・プロトコル・スイート|TCP/IP]] のライブラリを備えており、ネットワークで[[ソケット (BSD)|ソケット]]通信を行うソフトウェアを簡単に実装できた。分散オブジェクト環境 ([[Java Remote Method Invocation|Java RMI]], [[Common Object Request Broker Architecture|CORBA]]) のソフトウェアの開発も早い時期からできるようになっていた。近年<sup class="noprint Inline-Template nowrap">[''[[Wikipedia:言葉を濁さない|いつ?]]'']</sup>では、さまざまな[[ネットワークプロトコル]]の高水準なライブラリが使えるようになっている。[[W3C]]により標準化された、汎用[[マークアップ言語]]のひとつである[[Extensible Markup Language|XML]]で記述された文書を扱うライブラリも早期に実装・標準サポートされた。近年<sup class="noprint Inline-Template nowrap">[''[[Wikipedia:言葉を濁さない|いつ?]]'']</sup>では、XMLプロセサと[[XSL Transformations|XSLT]]プロセサがJava標準ライブラリに統合され提供されている。充実したネットワーク機能とXML文書を扱う機能を有効に組み合わせることにより、Javaは標準機能だけでも高度なシステムを構築できる言語の一つとなっている。
172 ⟶ 176行目:
*Java実行環境の既定の設定では、遠隔のコンピュータ上にある実行コード(Javaアプレット)に対して、ローカルにあるファイル等へのアクセスや、アプレットのダウンロード元以外の遠隔コンピュータとの通信を禁止している。
===
Javaは[[例外処理]]の構文を備えている。これは制御フローの一種であり、例外想定ブロック内の実行中に状態異常が発生すると例外オブジェクトが生成されて、その宛先となる例外捕捉ブロックに強制ジャンプするという仕組みを指す。これは「例外を投げる」と形容されている。例外捕捉ブロックでは、渡された例外オブジェクトの情報に基づいた任意の処理を行った後に例外ブロックを抜ける事になった。
例外処理は様々なコード局面での使用が推奨されたが、例外発生後のコードが全スキップされるというフロー上の性質から例外想定ブロック内のコード行数は比較的少ないものとなり、それら例外ブロックの断続的な羅列は却ってソースコードの可読性低下にも繋がった。例外処理による堅牢性と、コーディングレベルでの利便性および実用性は様々な部分でマッチしなかったとも言える。また、実行中の多方面に影響が及ぶような致命的な例外ほど、単純な例外ブロックの記述では対応しきれず、細部の例外ブロックから更に大枠の例外ブロックへ飛ぶというような大胆なジャンプを頻発させてプログラムの把握が難しくなるという欠点もあった。結果的に例外処理は、入出力機能の呼び出しなど決まりきった状態異常の発生部分では積極的に用いられるが、それ以外ではコーディングの頻雑さに勝るだけの有用性がそれほど認められていないのが実情となっている。
=== その他 ===
Javaは「[[パッケージ (Java)|パッケージ]]」という[[名前空間]]を持つ。これはクラスとインタフェースを文字列レベルで分類し、またクラス名定義の衝突を回避するための機能である。パッケージ名は任意の数だけピリオドで繋ぐことができる。同時にこれはパッケージの階層構造を表現できる。パッケージの実体はクラス名に付ける接頭辞の羅列であり、その接頭辞文字列によってクラス名をユニークなものにしている。プログラミングの際はソースコード冒頭に、フルパス先頭から任意の数だけ指定したパッケージ名以降をワイルドカード化し、そのパッケージ内のクラスをデフォルト指定できるので短いコード記述が可能となる。
== Javaの歴史 ==
{{更新|date=2018年9月|section=1}}
447 ⟶ 452行目:
== Java言語の構文 ==
{{main|Javaの文法}}
構文は、[[C言語|C]]および[[C++]]から多くを引き継いでいる。このため、設計当時には割合として多かった、CやC++しか書けない[[プログラマ]]にも習得しやすいと、{{要出典範囲|date=2017年10月|メーカーや信者は宣伝した}}。Javaが設計された1990年代中旬以前は、Cのプログラマが多く、また[[オブジェクト指向プログラミング言語]]の中では、[[C++]]は広く使われてきた言語の一つだった。なお、JavaではC++と違って名前空間レベルの関数(メソッド)および変数(フィールド)の宣言および定義を許可しておらず、必ず何らかのクラス定義の中に記述することが特徴である。この特徴は後発の[[C Sharp|C#]]も踏襲している。
次の節以降では、[[Hello world]][[プログラム (コンピュータ)|プログラム]]で、Javaプログラムの例を示して説明する。Hello worldプログラムとは、"Hello, world" という文字列をディスプレイなどの出力装置に出力する簡単なソフトウェアプログラムである。プログラミング言語の初学者向けのプログラム例としてよく使われる。なお先に述べた通り、Javaには複数の実行形態があると考えることができるので、以降では、それぞれの実行形態におけるHello worldプログラムを例示する。
=== スタンドアロン(コマンドライン) ===
[[キャラクターユーザインタフェース|コマンドライン]]環境で動く[[スタンドアローン|スタンドアロン]]の[[Javaアプリケーション]]の例を示す。Javaでは、他のプログラミング言語と同様に、コマンドライン環境で動く[[プログラム (コンピュータ)|プログラム]]を簡単に開発できる。
<source lang="java">
// Hello.java
459 ⟶ 468行目:
</source>
このプログラムについて説明する。
*Javaのプログラムではすべてを<code>'''class'''</code>内に記述する。コマンドラインのスタンドアロンアプリケーションの場合も同じである。
*[[ソースコード]]の[[ファイル (コンピュータ)|ファイル]]名は、そのファイルで記述している[[クラス (コンピュータ)|クラス]]の名前に ".java" というサフィクス(接尾辞、[[拡張子]])を付けるという規則で命名する。
*:このプログラム例では、クラス名は<code>'''Hello'''</code>であるため、"Hello.java" というソースファイル名にする必要がある。
*[[コンパイラ]]は、ソースファイルで定義されている各クラスの[[Javaクラスファイル|クラスファイル]]([[バイトコード]])を生成する。クラスファイルの名称は、そのクラスの名前に ".class" のサフィクスをつけた名前になる。
**クラスファイルの生成において、内部クラスの一種である無名クラス (anonymous class) の場合は、クラスファイルの名称は、その無名クラスを含むクラスの名称と整数(0から始まり、無名クラスが複数ある場合は、さらに1、2...と順に付番される)を "$" で連結した文字列に、通常のクラスと同じく ".class" のサフィクスを付けた名前になる。
*この例のように、スタンドアロンで実行するプログラム(クラス)では<code>'''main()'''</code>[[メソッド (計算機科学)|メソッド]]を定義する必要がある。メソッド定義には振る舞いを記述する。このmainメソッドのシグニチャ(戻り値、引数)は次のようにしなければならない。
**戻り値の指定には<code>'''void'''</code>キーワードを使う。<code>void</code>は、そのメソッドが何も戻り値を返さないことを示す。
**mainメソッドは、パラメタ([[引数]])として1つの{{Javadoc:SE|java/lang|String}}の配列を受け取らなくてはならない。この<code>String</code>配列の引数の名称は<code>'''args'''</code>とすることが慣習となっている。ただし引数として可能な名称であれば他の名称でも構わない。
**mainメソッドには<code>'''static'''</code>キーワードをつけなければならない。<code>static</code>は、そのメソッドがクラスメソッドであることを示す。クラスメソッドは、[[クラス (コンピュータ)|クラス]]と関連するメソッドであり、[[オブジェクト (プログラミング)|オブジェクト]][[インスタンス]]に関連するメソッド([[インスタンスメソッド]])ではない。
**mainメソッドは<code>'''public'''</code>キーワードをつけて宣言する。publicは、そのメソッドが他のクラスのコードから呼び出せること、およびそのクラスが他のクラスから呼び出される可能性があることを、示す。ここでの「他のクラス」とは、そのクラスの継承階層に関係なく、他のすべてのクラスを意味する。
*印字出力機能は、Javaの標準[[ライブラリ]]に含まれている。'''{{Javadoc:SE|java/lang|System}}''' クラスは public static のフィールド '''{{Javadoc:SE|name=out|java/lang|System|out}}''' をもつ。<code>out</code> オブジェクトは、{{Javadoc:SE|java/io|PrintStream}} クラスのインスタンスであり、[[標準出力]]ストリームを表す。<code>PrintStream</code>クラスのインスタンスである <code>out</code> オブジェクトは、'''{{Javadoc:SE|name=println(String)|java/io|PrintStream|println(java.lang.String)}}''' メソッドを持つ。このメソッドはデータをストリームに出力する。[[ストリーム (プログラミング)|ストリーム]]とは入出力を[[抽象化 (計算機科学)|抽象化]]した概念である。この場合は、データを画面(<code>out</code> 、標準出力)に出力する。
*スタンドアロンプログラムを実行するには、Java実行環境に呼び出す対象となる main メソッドを持つクラスの名前を渡すことによって、Java実行環境に実行を指示する。 [[UNIX]]や[[Microsoft Windows|Windows]]の環境の場合は、カレント[[ディレクトリ]]から<code>java -cp . Hello</code>をコマンドラインで入力することで、この例のプログラム(Hello.classに[[コンパイル]]されたクラス)を実行することができる。
**実行するmainメソッドをもつクラス名の指定については、[[Jar|Javaアーカイブ]] (Jar) ファイルのMANIFESTに記述する方法もある。
=== スタンドアロン(GUIアプリ) ===
|