diff options
Diffstat (limited to 'files/ja/rhino')
-rw-r--r-- | files/ja/rhino/community/index.html | 16 | ||||
-rw-r--r-- | files/ja/rhino/download_rhino/index.html | 104 | ||||
-rw-r--r-- | files/ja/rhino/index.html | 20 | ||||
-rw-r--r-- | files/ja/rhino/scopes_and_contexts/index.html | 126 | ||||
-rw-r--r-- | files/ja/rhino/scripting_java/index.html | 377 |
5 files changed, 643 insertions, 0 deletions
diff --git a/files/ja/rhino/community/index.html b/files/ja/rhino/community/index.html new file mode 100644 index 0000000000..d0cae094d5 --- /dev/null +++ b/files/ja/rhino/community/index.html @@ -0,0 +1,16 @@ +--- +title: Rhino コミュニティ +slug: Rhino/Community +tags: + - Rhino + - 要更新 +translation_of: Mozilla/Projects/Rhino/Community +--- +<p>『<a href="/ja/docs/Rhino_documentation">Rhino に関する文書</a>』の中では答えを見つけることができない質問がありますか? ここでは、いくつかの追加のヘルプ情報を提供します。</p> +<h2 id="Mailing_List" name="Mailing_List">ニュースグループとメールゲートウェイ</h2> +<p>The <a class="link-news" href="news://news.mozilla.org/mozilla.dev.tech.js-engine.rhino">mozilla.dev.tech.js-engine.rhino</a> newsgroup answers questions about Rhino. Click <a class="link-https" href="https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino">here</a> to subscribe/unsubscribe.</p> +<p>The <a class="link-news" href="news://news.mozilla.org/mozilla.dev.tech.js-engine">mozilla.dev.tech.js-engine</a> newsgroup answers questions about the C implementation of JavaScript, and was also used for answering questions about Rhino until September 27, 2007. If you think you might be interested in it regardless, click <a class="link-https" href="https://lists.mozilla.org/listinfo/dev-tech-js-engine">here</a> to subscribe/unsubscribe.</p> +<p>To view archived messages, try <a href="http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/topics">Google group for Rhino</a> or other newsgroup services.</p> +<p>To view archived messages <i>earlier than</i> September 27, 2007, try <a href="http://groups.google.com/group/mozilla.dev.tech.js-engine/topics">Google group for the earlier newsgroup</a>.</p> +<h2 id="Bug_System" name="Bug_System">バグシステム</h2> +<p>Rhino についてのバグは <a class="link-https" href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Rhino">Bugzilla</a> を使ってください。注記: Rhino は、独立したカテゴリを持っています。</p> diff --git a/files/ja/rhino/download_rhino/index.html b/files/ja/rhino/download_rhino/index.html new file mode 100644 index 0000000000..fafffa5929 --- /dev/null +++ b/files/ja/rhino/download_rhino/index.html @@ -0,0 +1,104 @@ +--- +title: ダウンロード Rhino +slug: Rhino/Download_Rhino +translation_of: Mozilla/Projects/Rhino/Download_Rhino +--- +<p>Rhino は、ソースとコンパイル済み形式、両方をダウンロード可能です。</p> + +<h2 id="バイナリ">バイナリ</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">リリース</th> + <th scope="col">リリース日</th> + <th scope="col">リリースノート</th> + <th scope="col">ダウンロード</th> + </tr> + <tr> + <td>Rhino 1.7R4</td> + <td>2012-06-18</td> + <td><a href="/En/New_in_Rhino_1.7R4" title="En/New_in_Rhino_1.7R4">New in Rhino 1.7R4</a></td> + <td><a class="link-https" href="https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip" title="https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip">rhino1_7R4.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7R5</td> + <td>2015-01-29</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7R5_RELEASE">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7R5_RELEASE/rhino1_7R5.zip">rhino1_7R5.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.6</td> + <td>2015-04-15</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_6_RELEASE">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_6_RELEASE/rhino1.7.6.zip">rhino1.7.6.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.7</td> + <td>2015-06-17</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_RELEASE">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_7_RELEASE/rhino1.7.7.zip">rhino1.7.7.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.7.1</td> + <td>2016-02-01</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_1_RELEASE">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_7_1_RELEASE/rhino-1.7.7.1.zip">rhino1.7.7.1.zip </a></td> + </tr> + <tr> + <td>Rhino 1.7.7.2</td> + <td>2017-08-24</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_7_2_Release/rhino-1.7.7.2.zip">rhino1.7.7.2.zip </a></td> + </tr> + <tr> + <td>Rhino 1.7.8</td> + <td>2018-01-22</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_8_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_8_Release/rhino-1.7.8.zip">rhino1.7.8.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.9</td> + <td>2018-03-15</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_9_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_9_Release/rhino-1.7.9.zip">rhino1.7.9.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.10</td> + <td>2018-04-09</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_10_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_10_Release/rhino-1.7.10.zip">rhino1.7.10.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.11</td> + <td>2019-05-30</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_11_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_11_Release/rhino-1.7.11.zip">rhino1.7.11.zip</a></td> + </tr> + <tr> + <td>Rhino 1.7.12</td> + <td>2020-01-13</td> + <td><a href="https://github.com/mozilla/rhino/releases/tag/Rhino1_7_12_Release">リリース ノート</a></td> + <td><a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_12_Release/rhino-1.7.12.zip">rhino1.7.12.zip</a></td> + </tr> + </tbody> +</table> + +<p>より古いバージョンの Rhino をダウンロードするには、<a href="http://developer.mozilla.org/en/docs/Rhino_downloads_archive" hreflang="en">Rhino ダウンロード・アーカイブ</a> を参照してください。</p> + +<h2 id="ライセンス">ライセンス</h2> + +<p>Rhino はオープンソースです。リリース 1.7R4 以降はRhinoは <a class="external" href="http://www.mozilla.org/MPL/">MPL</a> 2.0 ライセンスに基づいて利用できます</p> + +<p>それ以前のバージョンは MPL 1.1/GPL 2.0 ライセンスの基にリリースされています。</p> + +<p>詳細な情報は <a href="/en/Rhino/License" title="en/Rhino license">Rhinoライセンス</a> を参照してください。</p> + +<h2 id="ソース">ソース</h2> + +<p>上記 zip ファイルからソースを得ることに加え、 github <a class="link-https" href="https://github.com/mozilla/rhino">https://github.com/mozilla/rhino</a> からもRhino ソースコードを見つけることができます。 次のコマンドを実行すればソースを入手できます。</p> + +<pre class="code">git clone https://github.com/mozilla/rhino.git +</pre> + +<p>Rhino のビルド・システムには <a class="ex-ref external" href="http://ant.apache.org/">Ant</a> を利用しています。 Rhino ディストリビューションのトップディレクトリで ant コマンドを走らせれば、利用可能なビルド対象のリストが表示されるはずです。</p> diff --git a/files/ja/rhino/index.html b/files/ja/rhino/index.html new file mode 100644 index 0000000000..58dd55c7a7 --- /dev/null +++ b/files/ja/rhino/index.html @@ -0,0 +1,20 @@ +--- +title: Rhino +slug: Rhino +translation_of: Mozilla/Projects/Rhino +--- +<div><img alt="Image:rhino.jpg" class="internal" src="/@api/deki/files/832/=Rhino.jpg"></div> + +<p><strong>Rhino</strong> はすべてが Java で記述された <a href="/ja/docs/JavaScript">JavaScript</a> のオープンソースな実装です。それは一般的には、Java アプリケーション環境へ組み込まれて、エンドユーザーによるスクリプトの記述が可能になります。J2SE 6 ではデフォルトの Java スクリプティングエンジンとして組み込まれています。</p> + +<h2 id=".E3.83.80.E3.82.A6.E3.83.B3.E3.83.AD.E3.83.BC.E3.83.89" name=".E3.83.80.E3.82.A6.E3.83.B3.E3.83.AD.E3.83.BC.E3.83.89">ダウンロード</h2> + +<p><a class="external" href="https://developer.mozilla.org/ja/docs/Rhino/Download_Rhino">ソースとバイナリを取得する</a> 方法。</p> + +<h2 id=".E3.83.89.E3.82.AD.E3.83.A5.E3.83.A1.E3.83.B3.E3.83.88" name=".E3.83.89.E3.82.AD.E3.83.A5.E3.83.A1.E3.83.B3.E3.83.88">ドキュメント</h2> + +<p>スクリプト記述者と組み込み開発者への <a href="/ja/docs/Rhino_documentation">Rhino の情報</a>。</p> + +<h2 id=".E3.83.98.E3.83.AB.E3.83.97" name=".E3.83.98.E3.83.AB.E3.83.97">ヘルプ</h2> + +<p>困ったときの <a href="/ja/docs/Rhino_help">いくつかのリソース</a>。</p> diff --git a/files/ja/rhino/scopes_and_contexts/index.html b/files/ja/rhino/scopes_and_contexts/index.html new file mode 100644 index 0000000000..5f9d70fa81 --- /dev/null +++ b/files/ja/rhino/scopes_and_contexts/index.html @@ -0,0 +1,126 @@ +--- +title: Rhino scopes and contexts +slug: Rhino/Scopes_and_Contexts +translation_of: Mozilla/Projects/Rhino/Scopes_and_Contexts +--- +<p>Rhinoをマルチスレッドの環境で使う前に、コンテキストとスコープの間の関係を理解することが大切です。両方ともスクリプトを実行するのに必要ですが、それぞれは異なる役割を担います。簡単なRhinoの埋め込みであればここに書いてある情報はあまり必要ではないでしょう。しかしより複雑な埋め込みやパフォーマンスと柔軟性を上げるためにはこれらのことが役に立つでしょう。</p> + +<h2 id="コンテキスト"><span id="contexts">コンテキスト</span></h2> + +<p>コンテキストオブジェクトは実行環境に関するスレッド固有の情報を保持するために使われます。それぞれのスレッドに関連付けられたJavaScript実行環境のコンテキストは一つだけであるべきです。</p> + +<p>現在のスレッドをコンテキストに関連付けるためには、 <code>enter</code> メソッドを呼びます:</p> + +<pre>Context cx = Context.enter(); +</pre> + +<p>実行が終わったら、コンテキストを抜けます:</p> + +<pre>Context.exit(); +</pre> + +<p>これらのコールはすでに現在のスレッドにコンテキストが関連付けられていたとしても、正しく動作します。これは内部的にカウンターをインクリメントします。カウンターが0になると、スレッドからの関連付けが解除されます。</p> + +<p><code>exit()</code> の呼び出しは実行中に例外が発生しても大丈夫なように、 <code>finally</code> ブロックで行うようにしてください。</p> + +<h2 id="スコープ"><span id="scopes">スコープ</span></h2> + +<p>スコープはJavaScriptオブジェクトのセットです。スクリプトの実行には <code>Function</code> や <code>Object </code>などのオブジェクトを保持しておくためのトップレベルスクリプト変数スコープを必要とします。</p> + +<p>スコープはそれを作成したコンテキストとは独立しているということを理解することが大事です。あるコンテキストでスコープを作り、それを別のコンテキストでスクリプトを評価することが可能です。(一度コンテキストを抜けて再度入った場合や、別のスレッドで実行する場合など) 同じスコープに関して複数のスレッドで同時にスクリプトを実行することもできます。RhinoはJavaScriptオブジェクトのプロパティへのアクセスの原始性を保証します。しかしそれ以外の同時に実行されるスクリプトの保証はしません。もし二つのスクリプトが同じスコープを同時に使用する場合、スクリプトは共有変数へのアクセスを制御する必要があります。</p> + +<p>トップレベルスコープは <code>Context.initStandardObjects</code> で作れます。</p> + +<pre>ScriptableObject scope = cx.initStandardObjects(); +</pre> + +<p>Rhinoを埋め込む最も簡単な方法は、必要に応じてこの方法で単に新しいスコープを作ることです。しかし <code>initStandardObjects</code> は高価なメソッドで、たくさんのメモリを確保します。複数のスコープやスレッドで作成したスコープを共有する方法は、後述します。</p> + +<h2 id="名前ルックアップ"><span id="namelookup">名前ルックアップ</span></h2> + +<p>ではどのようにスコープは名前を見つけるのに使われるのでしょう?簡単に言えば、変数は現在の変数から始まって (これはプログラム中でどんなコードが実行されるかによります)、プロトタイプチェインを辿ります。そして親子チェインを辿ります。下の図では、6個のオブジェクトが辿られる様子が描かれています。</p> + +<figure style="margin: 0.75em auto; text-align: center;"><img alt="" src="https://bug851266.bugzilla.mozilla.org/attachment.cgi?id=763083" style="height: 194px; width: 500px;"> +<figcaption>Order of lookups in a two-deep scope chain with prototypes.</figcaption> +</figure> + +<p>より具体的な例として、次のスクリプトを考えてみましょう:</p> + +<pre>var g = 7; + +function f(a) { + var v = 8, + x = v + a; +} + +f(6); +</pre> + +<p>トップレベル変数 <code>g</code> があり、 <code>f</code> の呼び出しは新たなトップレベル変数 <code>x </code>を作成します。全てのトップレベル変数はスコープオブジェクトのプロパティです。 <code>f</code> の実行を開始するとき、スコープチェインは関数のアクティベーションオブジェクトから開始し、トップレベルスコープで終わります (下図参照)。アクティベーションオブジェクトは二つのプロパティを持っています。'a' は引数、'v' は変数です。トップレベルスコープは変数 <code>g</code> と関数 <code>f</code> を持っています。</p> + +<figure style="margin: 0.75em auto; text-align: center;"><img src="https://bug851266.bugzilla.mozilla.org/attachment.cgi?id=763084" style="height: 496px; width: 820px;"> +<figcaption>シンプルなスクリプトのスコープチェインの例</figcaption> +</figure> + +<p><code>x = v + a;</code> というステートメントが実行されるとき、スコープチェインが辿られ 'x' プロパティを探します。何も見つからなければ新たな'x' プロパティがトップレベルスコープに作られます。</p> + +<h2 id="スコープの共有"><span id="sharingscopes">スコープの共有</span></h2> + +<p>JavaScriptはクラスベースの継承よりも委譲を使う言語です。これはそれ自体が大きなトピックですが、これにより複数のスコープで読み取り専用の変数を共有する簡単な方法が与えられます。</p> + +<p>これを行うためには、オブジェクトのプロトタイプを設定します。JavaScriptでオブジェクトのプロパティにアクセスするとき、与えられた名前をまずオブジェクトのプロパティから探します。もし見つからなければ、オブジェクトのプロトタイプを探しにいきます。これはプロトタイプチェインの最後に到達するまで続きます。</p> + +<p>なので、複数のスコープで情報を共有する場合、まず共有したいオブジェクトを作成します。通常このオブジェクトは <code>initStandardObjects</code> で作られます。組み込み用にいくつかの追加のオブジェクトを持つかもしれません。そしてさらに新しいオブジェクトを作成して、そのオブジェクトの <code>setPrototype</code>method を呼び、共有オブジェクトをプロトタイプに設定します。そして新しいスコープの親はnullにします:</p> + +<pre>Scriptable newScope = cx.newObject(sharedScope); +newScope.setPrototype(sharedScope); +newScope.setParentScope(null); +</pre> + +<p>The call to <code>newObject</code> simply creates a new JavaScript object with no properties. It uses the<code>sharedScope</code> passed in to initialize the prototype with the standard <code>Object.prototype</code> value.</p> + +<p>これで <code>newScope</code> をスクリプトを評価するスコープとして使うことができます。このスコープを<em>インスタンススコープ</em>と呼びましょう。スクリプトで定義される全てのトップレベル関数や変数はインスタンススコープのプロパティになります。Uses of standard objects like <code>Function</code>, <code>String</code>, or <code>RegExp</code> will find the definitions in the shared scope. Multiple instance scopes can be defined and have their own variables for scripts yet share the definitions in the shared scope. These multiple instance scopes can be used concurrently.</p> + +<h2 id="Sealed_shared_scopes"><span id="sealedshared">Sealed shared scopes</span></h2> + +<p>The ECMAScript standard defines that scripts can add properties to all standard library objects and in many cases it is also possible to change or delete their properties as well. Such behavior may not be suitable with shared scopes since if a script by mistake adds a property to a library object from the shared scope, that object would not be garbage collected until there are no active references to the shared scope potentially leading to memory leaks. In addition if a script alters some of the standard objects, the library may not work properly for other scripts. Such bugs are hard to debug and to remove a possibility for them to occur one can seal the shared scope and all its objects.</p> + +<p>A notion of a sealed object is a JavaScript extension supported by Rhino and it means that properties can not be added/deleted to the object and the existing object properties can not be changed. Any attempt to modify sealed object throws an exception. To seal all objects in the standard library pass<code>true</code> for the sealed argument when calling <code>Context.initStandardObjects(ScriptableObject, boolean)</code>:</p> + +<pre>ScriptableObject sealedSharedScope = cx.initStandardObjects(null, true); +</pre> + +<p>This seals only all standard library objects, it does not seal the shared scope itself thus after calling<code>initStandardObjects</code>, <code>sealedSharedScope</code> can be farther populated with application-specific objects and functions. Then after a custom initialization is done, one can seal the shared scope by calling<code>ScriptableObject.sealObject()</code>:</p> + +<pre>sealedSharedScope.sealObject(); +</pre> + +<p>Note that currently one needs to explicitly seal any additional properties he adds to the sealed shared scope since although after calling <code>sealedSharedScope.sealObject();</code> it would no be possible to set the additional properties to different values, one still would be able to alter the objects themselves.</p> + +<p>Note that currently in order to use Java classes (LiveConnect) from a sealed shared scope you need to pre-load a number of objects needed for LiveConnect into the scope before it gets sealed. These objects would normally be lazy loaded but the lazy loading fails if the scope is sealed.</p> + +<pre>ScriptableObject sealedSharedScope = cx.initStandardObjects(null, true); + +// Force the LiveConnect stuff to be loaded. +String loadMe = "RegExp; getClass; java; Packages; JavaAdapter;"; +cx.evaluateString(sealedSharedScope , loadMe, "lazyLoad", 0, null); +sealedSharedScope .sealObject();</pre> + +<h2 id="Dynamic_Scopes"><span id="dynamic">Dynamic Scopes</span></h2> + +<p>There's one problem with the setup outlined above. Calls to functions in JavaScript use <em>static scope</em>, which means that variables are first looked up in the function and then, if not found there, in the lexically enclosing scope. This causes problems if functions you define in your shared scope need access to variables you define in your instance scope.</p> + +<p>With Rhino 1.6, it is possible to use <em>dynamic scope</em>. With dynamic scope, functions look at the top-level scope of the currently executed script rather than their lexical scope. So we can store information that varies across scopes in the instance scope yet still share functions that manipulate that information reside in the shared scope.</p> + +<p>The <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/DynamicScopes.java">DynamicScopes example</a> illustrates all the points discussed above.</p> + +<h2 id="More_on_Scopes">More on Scopes</h2> + +<p>The key things to determine in setting up scopes for your application are</p> + +<ol> + <li>What scope should global variables be created in when your script executes an assignment to an undefined variable, and</li> + <li>What variables should your script have access to when it references a variable?</li> +</ol> + +<p>The answer to 1 determines which scope should be the ultimate parent scope: Rhino follows the parent chain up to the top and places the variable there. After you've constructed your parent scope chain, the answer to question 2 may indicate that there are additional scopes that need to be searched that are not in your parent scope chain. You can add these as prototypes of scopes in your parent scope chain. When Rhino looks up a variable, it starts in the current scope, walks the prototype chain, then goes to the parent scope and its prototype chain, until there are no more parent scopes left.</p> diff --git a/files/ja/rhino/scripting_java/index.html b/files/ja/rhino/scripting_java/index.html new file mode 100644 index 0000000000..f9d5c0c6f6 --- /dev/null +++ b/files/ja/rhino/scripting_java/index.html @@ -0,0 +1,377 @@ +--- +title: Java のスクリプティング +slug: Rhino/Scripting_Java +tags: + - Rhino +translation_of: Mozilla/Projects/Rhino/Scripting_Java +--- +<p>この記事では Rhino を使用して JavaScript を超えて Java に到達する方法を説明します。Java によるスクリプティングには多くの用途があります。これは、利用可能な多くの Java ライブラリを利用して、強力なスクリプトを素早く作成することを可能にします。スクリプトを書くことで Java クラスをテストできます。 私たちは、探索的プログラミングのためのスクリプトを使用して、Java 開発を支援することもできます。探索的プログラミングとは、ライブラリや API がそれを使用するクイックプログラムを書くことによって何ができるのかを学習するプロセスです。ここからわかるように、スクリプトによってこのプロセスが簡単になります。</p> + +<p>ECMA 標準では Java (またはそのような外部オブジェクトシステムとの通信) は扱いません。したがって、この章で扱うすべての機能を拡張機能と見なす必要があります。</p> + +<h3 id="Accessing_Java_Packages_and_Classes" name="Accessing_Java_Packages_and_Classes">Java パッケージとクラスへのアクセス</h3> + +<p>すべての Java コードはクラスの一部です。すべての Java クラスはパッケージの一部です。ただし、JavaScript では、スクリプトはパッケージ階層の外に存在します。どうしたら Java パッケージのクラスにアクセスできるでしょうか?</p> + +<p>Rhino は <code style="font-size: 1em; white-space: nowrap;">Packages</code> という名前の最上位変数を定義します。<code style="font-size: 1em; white-space: nowrap;">Packages</code> 変数のプロパティはすべて <code style="font-size: 1em; white-space: nowrap;">java</code> や <code style="font-size: 1em; white-space: nowrap;">com</code> などのトップレベルの Java パッケージです。たとえば、<code style="font-size: 1em; white-space: nowrap;">java</code> パッケージの値にアクセスできます。</p> + +<pre class="code">js> Packages.java +[JavaPackage java]</pre> + +<p>便利なショートカットとして、Rhino は <code>Packages.java</code> と同等のトップレベルの変数 <code>java</code> を定義しています。したがって、前の例はさらに短くなる可能性があります。</p> + +<pre class="code">js> java +[JavaPackage java] +</pre> + +<p>パッケージの階層を下げるだけで Java クラスにアクセスできます。</p> + +<pre class="code">js> java.io.File +[JavaClass java.io.File] +</pre> + +<p>スクリプトが多数の異なる Java クラスにアクセスすると、毎回そのクラスの完全なパッケージ名を使用するのが面倒になることがあります。Rhino は Java の <code>import</code> 宣言と同じ目的を果たすトップレベル関数 <code>importPackage</code> を提供します。たとえば、<code>java.io</code> パッケージ内のすべてのクラスをインポートし、<code>File</code> という名前だけを使用して <code>java.io.File</code> クラスにアクセスできます。</p> + +<pre class="code">js> importPackage(java.io) +js> File +[JavaClass java.io.File] +</pre> + +<p>ここで <code>importPackage(java.io)</code> は、<code>java.io</code> パッケージ内のすべてのクラス (<code>File</code> など) を最上位レベルで使用可能にします。これは <code>import java.io.*;</code> Java 宣言と実質的に同じです。</p> + +<p>Java では <code>java.lang.*</code> が暗黙的にインポートされるのに対し、Rhino はそうでないことに注意することが重要です。その理由は、JavaScript には <code>java.lang</code> パッケージで定義された名前とは異なる独自のトップレベルオブジェクト <code>Boolean</code>、<code>Math</code>、<code>Number</code>、<code>Object</code>、および <code>String</code> があるからです。この競合のため、<code>java.lang</code> パッケージで <code>importPackage</code> を使用しないことをお勧めします。</p> + +<p>注意すべき点の1つは、Rhino が Java パッケージまたはクラス名を指定する際にエラーを処理することです。<code>java.MyClass</code> にアクセスすると、Rhino は <code>java.MyClass</code> という名前のクラスのロードを試みます。そのロードに失敗すると、<code>java.MyClass</code> はパッケージ名であるとみなされ、エラーは報告されません。</p> + +<pre class="code">js> java.MyClass +[JavaPackage java.MyClass] +</pre> + +<p>このオブジェクトをクラスとして使用しようとした場合にのみ、エラーが報告されます。</p> + +<h4 id="External_Packages_and_Classes" name="External_Packages_and_Classes">外部パッケージとクラス</h4> + +<p>Rhino で外部パッケージやクラスを使用することもできます。<code>.jar</code> または <code>.class</code> ファイルがクラスパス上にあることを確認してから、JavaScript アプリケーションにインポートすることができます。これらのパッケージは <code>java</code> パッケージにはない可能性が高いので、パッケージ名の前に "<code>Packages.</code>" を付ける必要があります。たとえば、<code>org.mozilla.javascript</code> パッケージをインポートするには、次のように <code>importPackage()</code> を使用できます。</p> + +<pre class="code">$ java org.mozilla.javascript.tools.shell.Main +js> importPackage(Packages.org.mozilla.javascript); +js> Context.currentContext; +org.mozilla.javascript.Context@bb6ab6 +</pre> + +<p>場合によっては、<code>importClass()</code> メソッドを使用してインポートするのではなく、例にあるようにパッケージの完全修飾名を使用します。これも可能ですが、入力が増えます。完全修飾名を使用すると、上記の例は次のようになります。</p> + +<pre class="code">$ java org.mozilla.javascript.tools.shell.Main +js> jsPackage = Packages.org.mozilla.javascript; +[JavaPackage org.mozilla.javascript] +js> jsPackage.Context.currentContext; +org.mozilla.javascript.Context@bb6ab6 +</pre> + +<p>また、パッケージから1つのクラスだけをインポートする場合は、<code>importClass()</code> メソッドを使用してクラスをインポートできます。上記の例は、次のように表すことができます。</p> + +<pre>$ java org.mozilla.javascript.tools.shell.Main +js> importClass(Packages.org.mozilla.javascript.Context); +js> Context.currentContext; +org.mozilla.javascript.Context@bb6ab6</pre> + +<h3 id="Working_With_Java" name="Working_With_Java">Java をあわせて使用する</h3> + +<p>Java クラスにアクセスできるようになったので、次の論理的なステップはオブジェクトを作成することです。これは、Java の場合と同様に <code>new</code> 演算子を使用して動作します。</p> + +<pre class="code">js> new java.util.Date() +Thu Jan 24 16:18:17 EST 2002 +</pre> + +<p>新しいオブジェクトを JavaScript 変数に格納すると、そのオブジェクトに対してメソッドを呼び出すことができます。</p> + +<pre class="code">js> f = new java.io.File("test.txt") +test.txt +js> f.exists() +true +js> f.getName() +test.txt +</pre> + +<p>静的メソッドおよびフィールドは、クラスオブジェクト自体からアクセスできます。</p> + +<pre class="code">js> java.lang.Math.PI +3.141592653589793 +js> java.lang.Math.cos(0) +1 +</pre> + +<p>JavaScript では、Java と異なり、メソッド自体はオブジェクトであり、呼び出されるだけでなく評価されます。メソッドオブジェクトを単独で表示すると、メソッドのさまざまなオーバーロードされた形式を見ることができます。</p> + +<pre class="code">js> f.listFiles +function listFiles() {/* +java.io.File[] listFiles() +java.io.File[] listFiles(java.io.FilenameFilter) +java.io.File[] listFiles(java.io.FileFilter) +*/} +</pre> + +<p>この出力は、<code>File</code> クラスが3つのオーバーロードされたメソッド <code>listFiles</code> を定義していることを示しています。1つは引数を取らず、他は <code>FilenameFilter</code> 引数を持つもの、<code>FileFilter</code> 引数を持つものです。すべてのメソッドは <code>File</code> オブジェクトの配列を返します。Java メソッドのパラメータと戻り値の型を見ることができるのは、メソッドを調べている可能性があり、パラメータや戻り値の型が不明な探索プログラミングで特に役立ちます。</p> + +<p>探索的プログラミングのもう1つの有用な機能は、オブジェクトに対して定義されたすべてのメソッドとフィールドを表示する機能です。JavaScript の <code>for..in</code> 構文を使用して、これらの値をすべて出力することができます:</p> + +<pre class="code">js> for (i in f) { print(i) } +exists +parentFile +mkdir +toString +wait +<em>[44 others]</em> +</pre> + +<p><code>File</code> クラスのメソッドだけでなく、(<code>wait</code> のような) 基本クラス <code>java.lang.Object</code> から継承されたメソッドもリストされていることに注意してください。これにより、深くネストされた継承階層のオブジェクトを扱うことが容易になります。これは、そのオブジェクトで使用可能なすべてのメソッドを見ることができるからです。</p> + +<p>Rhino は、JavaBeans のプロパティにプロパティ名で直接アクセスできるようにすることで、別の便利さを提供します。JavaBean のプロパティ <code>foo</code> は、<code>getFoo</code> と <code>setFoo</code> のメソッドで定義されています。さらに、同じ名前のブール値プロパティは、<code>isFoo</code> メソッドで定義することができます。たとえば、次のコードは実際に <code>File</code> オブジェクトの <code>getName</code> メソッドと <code>isDirectory</code> メソッドを呼び出します。</p> + +<pre class="code">js> f.name +test.txt +js> f.directory +false +</pre> + +<h3 id="Calling_Overloaded_Methods" name="Calling_Overloaded_Methods">オーバーロードされたメソッドの呼び出し</h3> + +<p>引数の型に基づいて呼び出すメソッドを選択するプロセスはオーバーロード解決と呼ばれます。Java では、オーバーロードの解決はコンパイル時に実行され、Rhino では実行時に行われます。第2章で議論したように、JavaScript の動的型指定を使用すると、この違いは避けられません。変数の型は実行時まで認識されないため、過負荷解決が発生するだけです。</p> + +<p>例として、いくつかのオーバーロードされたメソッドを定義し、それらを呼び出す以下の Java クラスを考えてみましょう。</p> + +<pre class="code">public class Overload { + + public String f(Object o) { return "f(Object)"; } + public String f(String s) { return "f(String)"; } + public String f(int i) { return "f(int)"; } + + public String g(String s, int i) { return "g(String,int)"; } + public String g(int i, String s) { return "g(int,String)"; } + + public static void main(String[] args) { + Overload o = new Overload(); + Object[] a = new Object[] { new Integer(3), "hi", Overload.class }; + for (int i = 0; i != a.length; ++i) + System.out.println(o.f(a[i])); + } +} +</pre> + +<p>プログラムをコンパイルして実行すると、出力が生成されます</p> + +<pre class="code">f(Object) +f(Object) +f(Object) +</pre> + +<p>しかし、同様のスクリプトを書くと</p> + +<pre class="code">var o = new Packages.Overload(); +var a = [ 3, "hi", Packages.Overload ]; +for (var i = 0; i != a.length; ++i) + print(o.f(a[i])); +</pre> + +<p>それを実行すると、出力が得られます</p> + +<pre class="code">f(int) +f(String) +f(Object) +</pre> + +<p>Rhino は実行時にオーバーロードされたメソッドを選択するため、引数に一致するより具体的な型を呼び出します。その間、Java はコンパイル時に引数の型だけでオーバーロードされたメソッドを選択します。</p> + +<p>これは、各呼び出しでより良い一致が可能なメソッドを選択する利点がありますが、より多くの作業が行われるためパフォーマンスに影響します。実際には、この性能コストは実際のアプリケーションでは顕著ではありません。</p> + +<p>過負荷の解決は実行時に発生するため、実行時に失敗する可能性があります。たとえば、<code>Overload</code> のメソッド <code>g</code> を2つの整数で呼び出すと、どちらのメソッドの形式も他よりも引数の型が近くないため、エラーが発生します。</p> + +<pre class="code">js> o.g(3,4) +js:"<stdin>", line 2: The choice of Java method Overload.g +matching JavaScript argument types (number,number) is ambiguous; +candidate methods are: +class java.lang.String g(java.lang.String,int) +class java.lang.String g(int,java.lang.String) +</pre> + +<p>オーバーロードセマンティクスのより正確な定義については、<a href="http://web.archive.org/web/20110623074154/http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">Java メソッドのオーバーロードと LiveConnect 3</a> を参照してください。</p> + +<h3 id="Implementing_Java_Interfaces" name="Implementing_Java_Interfaces">Java インターフェイスの実装</h3> + +<p>Java クラスにアクセスし、Java オブジェクトを作成し、それらのオブジェクトのフィールド、メソッド、プロパティにアクセスできるようになったので、私たちはすぐに大きな力を持っています。しかし、それだけでは不十分な例がいくつかあります。Java の多くの API は、クライアントが実装しなければならないインターフェースを提供することで機能します。その1つの例は <code>Thread</code> クラスです。そのコンストラクタは、新しいスレッドが開始されたときに呼び出される単一メソッドの <code>run</code> を含む <code>Runnable</code> を取ります。</p> + +<p>このニーズに対応するため、Rhino はインターフェイスを実装する新しい Java オブジェクトを作成する機能を提供します。まず、Java インターフェイスで必要とされるメソッドと名前が一致する関数プロパティーを持つ JavaScript オブジェクトを定義する必要があります。<code>Runnable</code> を実装するには、パラメータを指定せずに実行するメソッドを1つだけ定義する必要があります。第3章から覚えていれば、{propertyName:value} 表記で JavaScript オブジェクトを定義することは可能です。この構文を関数式と組み合わせて使用すると、run メソッドで JavaScript オブジェクトを定義できます。</p> + +<pre class="code">js> obj = { run: function () { print("\nrunning"); } } +[object Object] +js> obj.run() + +running +</pre> + +<p><code>Runnable</code> を構築することによって、<code>Runnable</code> インターフェイスを実装するオブジェクトを作成できます。</p> + +<pre class="code">js> r = new java.lang.Runnable(obj); +[object JavaObject] +</pre> + +<p>Java ではインプリメンテーションが利用できないため、インターフェイス上で <code>new</code> 演算子を使用することはできません。ここで Rhino は JavaScript オブジェクト <code>obj</code> から実装を取得します。<code>Runnable</code> を実装するオブジェクトができたので、<code>Thread</code> を作成して実行することができます。<code>run</code> に対して定義した関数は、新しいスレッドで呼び出されます。</p> + +<pre class="code">js> t = new java.lang.Thread(r) +Thread[Thread-2,5,main] +js> t.start() +js> + +running +</pre> + +<p>最後の <code>js</code> プロンプトと新しいスレッドからの出力は、スレッドのスケジューリングに応じてどちらの順序でも表示されます。</p> + +<p>Rhino は <code>Runnable</code> を実装する新しい Java クラスのバイトコードを生成し、<code>run</code> メソッドへのすべての呼び出しを関連する JavaScript オブジェクトに転送します。このクラスを実装するオブジェクトは Java アダプタと呼ばれます。JavaScript への転送は実行時に行われるため、呼び出されるまでインターフェイスを実装するメソッドの定義を遅らせることができます。必要なメソッドを省略することは大規模なプログラミングにおいては悪い習慣ですが、小さなスクリプトや探索的プログラミングには便利です。</p> + +<h3 id="The_JavaAdapter_Constructor" name="The_JavaAdapter_Constructor">JavaAdapter コンストラクタ</h3> + +<p>前のセクションでは、Java インターフェイスで <code>new</code> 演算子を使用して Java アダプタを作成しました。このアプローチには限界があります。複数のインターフェイスを実装することは不可能であり、非抽象クラスを拡張することもできません。これらの理由から、<code>JavaAdapter</code> コンストラクタがあります。</p> + +<p><code>JavaAdapter</code> コンストラクタの構文は次のとおりです。</p> + +<pre class="code">new JavaAdapter(javaIntfOrClass, [javaIntf, ..., javaIntf,] javascriptObject) +</pre> + +<p>ここで <code>javaIntfOrClass</code> は実装するインターフェイスまたは拡張するクラスであり、<code>javaIntf</code> は実装するための追加のインターフェイスです。<code>javascriptObject</code> は、Java アダプタから呼び出されるメソッドを含む JavaScript オブジェクトです。</p> + +<p>実際には、<code>JavaAdapter</code> コンストラクタを直接呼び出す必要はほとんどありません。ほとんどの場合、<code>new</code> 演算子を使用する前の構文で十分です。</p> + +<h3 id="JavaScript_Functions_as_Java_Interfaces" name="JavaScript_Functions_as_Java_Interfaces">Java インターフェイスとしての JavaScript 関数</h3> + +<p>多くの場合、前述の <code>Runnable</code> の例のように、またはさまざまなイベントリスナの実装を提供する場合のように、1つのメソッドだけを持つインターフェイスを実装する必要があります。 これを容易にするために、Rhino はそのようなインターフェイスが期待されるときに JavaScript 関数を渡すことができます。この関数はインターフェイスメソッドの実装として呼び出されます。</p> + +<p>以下は単純化された <code>Runnable</code> の例です:</p> + +<pre class="code">js> t = java.lang.Thread(function () { print("\nrunning"); }); +Thread[Thread-0,5,main] +js> t.start() +js> +running +</pre> + +<p>Rhino では、すべてのメソッドが同じシグネチャを持つ場合、複数のメソッドを持つ Java インターフェイスの実装として JavaScript 関数を使用することもできます。関数を呼び出すと、Rhino はメソッドの名前を追加の引数として渡します。関数は、呼び出されたメソッドに代わって関数を使用して区別できます。</p> + +<pre class="code">js> var frame = new Packages.javax.swing.JFrame(); +js> frame.addWindowListener(function(event, methodName) { + if (methodName == "windowClosing") { + print("Calling System.exit()..."); java.lang.System.exit(0); + } + }); +js> frame.setSize(100, 100); +js> frame.visible = true; +true +js> Calling System.exit()... +</pre> + +<h3 id="Creating_Java_Arrays" name="Creating_Java_Arrays">Java 配列の作成</h3> + +<p>Rhino には Java 配列を作成するための特別な構文はありません。このためには <code>java.lang.reflect.Array</code> クラスを使用する必要があります。5つの Java 文字列の配列を作成するには次の呼び出しを行います。</p> + +<pre class="code">js> a = java.lang.reflect.Array.newInstance(java.lang.String, 5); +[Ljava.lang.String;@7ffe01 +</pre> + +<p>プリミティブ型の配列を作成するには、<code>java.lang</code> パッケージの関連オブジェクトクラスで定義されている特殊な TYPE フィールドを使用する必要があります。たとえば、バイトの配列を作成するには特別なフィールド <code>java.lang.Byte.TYPE</code> を使用する必要があります。</p> + +<pre class="code">js> a = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2); +[C@7a84e4 +</pre> + +<p>結果の値は、その型の Java 配列が許可されている任意の場所で使用できます。</p> + +<pre class="code">js> a[0] = 104 +104 +js> a[1] = 105 +105 +js> new java.lang.String(a) +hi +</pre> + +<h3 id="Java_Strings_and_JavaScript_Strings" name="Java_Strings_and_JavaScript_Strings">Java 文字列と JavaScript 文字列</h3> + +<p>Java 文字列と JavaScript 文字列は同じ<strong>ではない</strong>ことに注意してください。Java 文字列は <code>java.lang.String</code> 型のインスタンスであり、そのクラスによって定義されたすべてのメソッドを持ちます。JavaScript 文字列には <code>String.prototype</code> で定義されたメソッドがあります。最も一般的な障害は <code>length</code> です。これは Java 文字列のメソッドであり、JavaScript 文字列の動的プロパティです。</p> + +<pre class="code">js> javaString = new java.lang.String("Java") +Java +js> jsString = "JavaScript" +JavaScript +js> javaString.length() +4 +js> jsString.length +10 +</pre> + +<p>Rhino は2つの型の違いを減らすための助けとなります。まず Java 文字列を Java メソッドに渡し、Rhino が変換を実行します。 前の例の <code>java.lang.String</code> コンストラクタの呼び出しで実際にこの機能が動作していました。</p> + +<p>Rhino は、java.lang.String クラスがまだそれらを定義していない場合、JavaScript メソッドを Java 文字列で使用できるようにします。例えば:</p> + +<pre class="code">js> javaString.match(/a.*/) +ava +</pre> + +<h3 id="JavaImporter_Constructor" name="JavaImporter_Constructor">JavaImporter コンストラクタ</h3> + +<p><code>JavaImporter</code> は、Java のスクリプト作成時に明示的なパッケージ名を省略できる新しいグローバルコンストラクタです。</p> + +<pre>var SwingGui = JavaImporter(Packages.javax.swing, + Packages.javax.swing.event, + Packages.javax.swing.border, + java.awt.event, + java.awt.Point, + java.awt.Rectangle, + java.awt.Dimension); +... + +with (SwingGui) { + var mybutton = new JButton(test); + var mypoint = new Point(10, 10); + var myframe = new JFrame(); +... +} +</pre> + +<p>これまでこのような機能は <a href="/ja/docs/Rhino"><code>org.mozilla.javascript.ImporterTopLevel</code></a> クラスをトップレベルのスコープとして使用した埋め込みにのみ使用できました。このクラスでは、スクリプト用の <code>importPackage()</code> および <code>importClass()</code> グローバル関数が追加されていますが、広範囲に使用すると Java クラスの名前でグローバル名前空間が汚染され、ロードされたクラスがガベージコレクションから保護されます。</p> + +<p>詳細については <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=245882">Bugzilla 245882</a> を参照してください。</p> + +<h3 id="Java_Exceptions" name="Java_Exceptions">Java 例外</h3> + +<p>Java メソッドによってスローされた例外は、<a href="/ja/docs/JavaScript/Guide/Exception_Handling_Statements/try...catch_Statement">try ... catch 文</a>を使用して JavaScript コードで捕捉できます。Rhino は Java 例外を次のプロパティを持つエラーオブジェクトにラップします。</p> + +<ul> + <li><code>javaException</code>: Java メソッドによってスローされた元の例外</li> + <li><code>rhinoException</code>: Rhino ランタイムでラップされた例外</li> +</ul> + +<p><code>instanceof</code> 演算子を使用すると、例外の型を問い合せることができます。</p> + +<pre>try { + java.lang.Class.forName("NonExistingClass"); +} catch (e) { + if (e.javaException instanceof java.lang.ClassNotFoundException) { + print("Class not found"); + } +} +</pre> + +<p>Rhino は、例外の条件付きキャッチを定義する try ... catch ステートメントの拡張もサポートしています。</p> + +<pre>function classForName(name) { + try { + return java.lang.Class.forName(name); + } catch (e if e.javaException instanceof java.lang.ClassNotFoundException) { + print("Class " + name + " not found"); + } catch (e if e.javaException instanceof java.lang.NullPointerException) { + print("Class name is null"); + } +} + +classForName("NonExistingClass"); +classForName(null); +</pre> |