aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/javascript/guide/liveconnect_overview/index.html
blob: 4deeca4ad27bdc27cccbb3ffa390d9e24c02b361 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
---
title: LiveConnect の概要
slug: Web/JavaScript/Guide/LiveConnect_Overview
tags:
  - Java
  - JavaScript
  - LiveConnect
translation_of: Archive/Web/LiveConnect/LiveConnect_Overview
---
<p>この章では、Java のコードと JavaScript のコードが相互通信を可能にする技術である <a href="/ja/docs/LiveConnect" title="ja/docs/LiveConnect">LiveConnect</a> の使用方法を解説します。この章の読者は、Java プログラミングの経験があるものとします。</p>

<h2 id="Working_with_Wrappers" name="Working_with_Wrappers">ラッパの使用</h2>

<p>JavaScript において、<em>ラッパ</em>とは元の言語のオブジェクトをくるんだ、ターゲットとする言語のデータ型のオブジェクトです。JavaScript でプログラミングをするときは、ラッパオブジェクトを用いることで Java のメソッドやフィールドにアクセスすることができます。つまり、ラッパのメソッドを呼び出したりプロパティにアクセスすることで、Java のオブジェクトにおいて呼び出すことになります。Java 側では JavaScript のオブジェクトがクラス <code>netscape.javascript.JSObject</code> のインスタンスでラップされ、Java に渡されます。</p>

<p>JavaScript のオブジェクトが Java に送られる際、ランタイムエンジンは <code>JSObject</code> 型の Java ラッパを生成します。一方 <code>JSObject</code> が Java から JavaScript に送られるときは、ランタイムエンジンはそのラップを解き、元の JavaScript オブジェクトの種類に戻します。<code>JSObject</code> クラスには、JavaScript のメソッドを呼び出したり JavaScript のプロパティを調べるためのインタフェースが備わっています。</p>

<h2 id="JavaScript_to_Java_Communication" name="JavaScript_to_Java_Communication">JavaScript から Java への通信</h2>

<p>Java のパッケージやクラスを参照したり、Java のオブジェクトや配列を扱ったりするときは、特別な LiveConnect オブジェクトを使用します。JavaScript から Java へのアクセスはすべて、これらのオブジェクトを用いて行います。それらのオブジェクトについて、以下の表で簡単にまとめます。</p>

<table class="standard-table">
 <caption>表 9.1 LiveConnect オブジェクト</caption>
 <thead>
  <tr>
   <th scope="col">オブジェクト</th>
   <th scope="col">説明</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>JavaArray</code></td>
   <td>ラップされた Java の配列です。JavaScript コード内からアクセスされます。</td>
  </tr>
  <tr>
   <td><code>JavaClass</code></td>
   <td>Java のクラスへの JavaScript からの参照です。</td>
  </tr>
  <tr>
   <td><code>JavaObject</code></td>
   <td>ラップされた Java のオブジェクトです。JavaScript コード内からアクセスされます。</td>
  </tr>
  <tr>
   <td><code>JavaPackage</code></td>
   <td>Java のパッケージへの JavaScript からの参照です。</td>
  </tr>
 </tbody>
</table>

<p><strong>注意:</strong> Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために JavaScript ランタイムエンジンが引数の値を適当なデータ型に変換します。詳細は<a href="/ja/docs/JavaScript/Guide/Values,_Variables,_and_Literals#Data_type_conversion" title="ja/docs/JavaScript/Guide/Values, Variables, and Literals#Data Type Conversion">データ型の変換</a>をご覧ください。</p>

<p>かなり直感的に Java とやりとりできることから、ある意味で LiveConnect オブジェクトの存在は透過的です。例えば、次のように Java の <code>String</code> オブジェクトを作成し、<code>new</code> 演算子を Java のコンストラクタとともに用いて、そのオブジェクトを JavaScript の変数 <code>myString</code> に代入することができます:</p>

<pre class="brush: js">var myString = new java.lang.String("Hello world");
</pre>

<p>この例では、変数 <code>myString</code><code>JavaObject</code> になります。これは、Java の <code>String</code> オブジェクトのインスタンスを保持しているためです。<code>JavaObject</code> であるので、<code>myString</code><code>java.lang.String</code> およびそのスーパークラスである <code>java.lang.Object</code> のパブリックなインスタンスメソッドにアクセスできます。これらの Java のメソッドは JavaScript から、<code>JavaObject</code> のメソッドとして使用できます:</p>

<pre class="brush: js">myString.length(); // 11 を返す
</pre>

<p>JavaClass オブジェクトの静的メンバは直接呼び出すことができます。</p>

<pre class="brush: js">alert(java.lang.Integer.MAX_VALUE); // 2147483647 というアラート
</pre>

<h3 id="The_Packages_Object" name="The_Packages_Object">Packages オブジェクト</h3>

<p>Java のクラスが <code>java</code><code>sun</code> あるいは <code>netscape</code> パッケージのいずれの一部でもない場合は、<code>Packages</code> オブジェクトを用いてそれにアクセスします。例えば Redwood 社が、実装したさまざまな Java のクラスを格納するための、<code>redwood</code> という名前の Java パッケージを使用することを想定します。<code>redwood</code><code>HelloWorld</code> クラスのインスタンスを作成するには、次のようにそのクラスのコンストラクタにアクセスします:</p>

<pre class="brush: js">var red = new Packages.redwood.HelloWorld();
</pre>

<p>デフォルトパッケージのクラス (すなわち、明示的にはパッケージに名前をつけていないクラス) にアクセスすることもできます。例えば、HelloWorld クラスが直接 <code>CLASSPATH</code> に入っており、またパッケージには入っていない場合は、次のようにしてそれにアクセスできます:</p>

<pre class="brush: js">var red = new Packages.HelloWorld();
</pre>

<p>LiveConnect の <code>java</code><code>sun</code> および <code>netscape</code> オブジェクトはよく使用される Java のパッケージであるために、短縮記法が備わっています。例えば、次のように使用できます:</p>

<pre class="brush: js">var myString = new java.lang.String("Hello world");
</pre>

<p>これは次のものを省略したものです:</p>

<pre class="brush: js">var myString = new Packages.java.lang.String("Hello world");
</pre>

<h3 id="Working_with_Java_Arrays" name="Working_with_Java_Arrays">Java の配列の使用</h3>

<p>Java のメソッドが配列を作成し、JavaScript からその配列を参照するときは、<code>JavaArray</code> を使用します。例えば、次のコードは int 型の要素を 10 個持つ <code>JavaArray x</code> を作成します:</p>

<pre class="brush: js">var x = java.lang.reflect.Array.newInstance(java.lang.Integer, 10);
</pre>

<p>JavaScript の <code>Array</code> オブジェクトのように、<code>JavaArray</code> にはその配列の要素数を返す <code>length</code> プロパティがあります。<code>Array.length</code> とは異なり、<code>JavaArray.length</code> は読み取り専用のプロパティです。これは、Java の配列は作成時に要素総数が固定されるためです。</p>

<h3 id="Package_and_Class_References" name="Package_and_Class_References">パッケージおよびクラスの参照</h3>

<p>JavaScript から Java のパッケージやクラスへの簡単な参照では、<code>JavaPackage</code><code>JavaClass</code> オブジェクトが作成されます。先の Redwood 社についての例では、例えば Packages.redwood という参照が JavaPackage オブジェクトです。同様に、<code>java.lang.String</code> のような参照は <code>JavaClass</code> オブジェクトです。</p>

<p>ほとんどの場合は <code>JavaPackage</code><code>JavaClass</code> オブジェクトについて気にする必要はありません。ただ Java のパッケージを使うだけのことであり、LiveConnect がこれらのオブジェクトを透過的に生成するからです。LiveConnect がクラスの読み込みに失敗する場合があり、そのときは以下のようにして手動で読み込みを行う必要があります:</p>

<pre class="brush: js">var Widgetry = java.lang.Thread.currentThread().getContextClassLoader().loadClass("org.mywidgets.Widgetry");
</pre>

<p>JavaScript 1.3 以前では <code>JavaClass</code> オブジェクトをパラメータとして Java のメソッドとして渡す際に、自動的には <code>java.lang.Class</code> のインスタンスに変換されません。そのため、<code>java.lang.Class</code> のインスタンスのラッパを作成しなければなりません。次の例では、<code>forName</code> メソッドがラッパオブジェクトである <code>theClass</code> を生成します。そしてそれを <code>newInstance</code> メソッドに渡し、配列を生成します。</p>

<pre class="brush: js">// JavaScript 1.3
var theClass = java.lang.Class.forName("java.lang.String");
var theArray = java.lang.reflect.Array.newInstance(theClass, 5);
</pre>

<p>JavaScript 1.4 以降では次の例のように、<code>JavaClass</code> オブジェクトをメソッドに直接渡すことができます:</p>

<pre class="brush: js">// JavaScript 1.4
var theArray = java.lang.reflect.Array.newInstance(java.lang.String, 5);
</pre>

<h3 id="Arguments_of_Type_char" name="Arguments_of_Type_char">char 型の引数</h3>

<p>JavaScript 1.4 以降では <code>char</code> 型の引数を必要とする Java のメソッドに、1 文字の文字列を渡すことができます。例えば、次のようにして文字列 "H" を <code>Character</code> コンストラクタに渡すことができます:</p>

<pre class="brush: js">var c = new java.lang.Character("H");
</pre>

<p>JavaScript 1.3 以前では、このようなメソッドにはその文字の Unicode 値に対応する整数値を渡さなければなりません。例えば、次のコードも "H" という文字列を変数 <code>c</code> に代入するものです:</p>

<pre class="brush: js">var c = new java.lang.Character(72);
</pre>

<h3 id="Handling_Java_Exceptions_in_JavaScript" name="Handling_Java_Exceptions_in_JavaScript">JavaScript での Java 例外の処理</h3>

<p>Java のコードは実行時に失敗すると、例外を投げます。JavaScript のコードが Java のデータメンバまたはメソッドにアクセスし、失敗すると、Java の例外が JavaScript に渡されます。これは、例外を処理できるようにするためです。JavaScript 1.4 からは <code>try...catch</code> 文でこの例外を受け取ることができます。(Mozilla 固有の LiveConnect コードが Mozilla 内でメンテナンスされていなかったため、この機能は (他の一部機能もあわせて) Gecko 1.9 で壊れています (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=391642" title="Try-catch sometimes does not catch Java LiveConnect exceptions but instead fails">バグ 391642</a> をご覧ください)。しかし Java 6 アップデート 11 および 12 での、Mozilla の汎用 (かつクロスブラウザの) <a href="/ja/docs/Plugins" title="ja/docs/Plugins">NPAPI</a> プラグインコードに依存する構築のサポートにより修復されました。)</p>

<p>例えば、Java の <code>forName</code> メソッドを使用して Java のクラス名を <code>theClass</code> という変数に代入するとします。<code>forName</code> メソッドに渡す値が Java のクラス名に評価できなければ、そのメソッドは例外を投げます。次のようにして、例外を処理できるように <code>forName</code> 代入文を <code>try</code> ブロック内に置きます:</p>

<pre class="brush: js">function getClass(javaClassName) {
   try {
      var theClass = java.lang.Class.forName(javaClassName);
   } catch (e) {
      return ("The Java exception is " + e);
   }
   return theClass;
}
</pre>

<p>この例では、<code>javaClassName</code> が "java.lang.String" のような正当なクラス名に評価されると代入が成功します。<code>javaClassName</code> が "String" のような不正なクラス名に評価されると、<code>getClass</code> 関数が例外を受け取り、次のようなものを返します:</p>

<pre>The Java exception is java.lang.ClassNotFoundException: String
</pre>

<p>例外の型に基づいて特別な処理をするには <code>instanceof</code> 演算子を使用します:</p>

<pre class="brush: js">try {
  // ...
} catch (e) {
  if (e instanceof java.io.FileNotFound) {
     // FileNotFound についての処理
  } else {
    throw e;
  }
}
</pre>

<p>JavaScript の例外についての詳細情報は<a href="/ja/docs/JavaScript/Guide/Statements#Exception_Handling_Statements" title="ja/docs/JavaScript/Guide/Statements#Exception Handling Statements">例外処理文</a>を参照してください。</p>

<h2 id="Java_to_JavaScript_Communication" name="Java_to_JavaScript_Communication">Java から JavaScript への通信</h2>

<p>Java で JavaScript のオブジェクトを使用したい場合は、その Java ファイルに <code>netscape.javascript</code> パッケージをインポートしなければなりません。このパッケージは次のクラスを定義しています:</p>

<ul>
 <li><code><a href="/ja/docs/JavaScript/Reference/LiveConnect/JSObject" title="ja/docs/JavaScript/Reference/LiveConnect/JSObject">netscape.javascript.JSObject</a></code> : Java のコードから JavaScript のメソッドやプロパティにアクセスできるようにします。</li>
 <li><code><a href="/ja/docs/JavaScript/Reference/LiveConnect/JSException" title="ja/docs/JavaScript/Reference/LiveConnect/JSException">netscape.javascript.JSException</a></code> : Java のコードで JavaScript のエラーを処理できるようにします。</li>
</ul>

<p>これらのクラスの詳細は <a href="/ja/docs/JavaScript/Reference" title="ja/docs/JavaScript/Reference">JavaScript リファレンス</a>をご覧ください。</p>

<h3 id="Locating_the_LiveConnect_classes" name="Locating_the_LiveConnect_classes">LiveConnect クラスの場所の特定</h3>

<p>古いバージョンの Netscape ブラウザでは、これらのクラスがブラウザに同梱されていました。JavaScript 1.2 からは、これらのクラスは .jar ファイルに格納されています。それより古いバージョンの JavaScript では、これらのクラスは .zip ファイルに格納されています。例えば Windows NT 向けの Netscape Navigator 4 では、クラスは Navigator のディレクトリ直下の <code>Program\Java\Classes</code> ディレクトリ内の <code>java40.jar</code> ファイルに格納されています。</p>

<p>より最近では、クラスは Sun の Java ランタイムに同梱されています。はじめはランタイムディストリビューションの "jre/lib" ディレクトリ内の "jaws.jar" ファイルに入っていましたが (JRE 1.3)、その後同じ場所の "plugin.jar" に移っています (JRE 1.4 以降)。</p>

<h3 id="Using_the_LiveConnect_classes_with_the_JDK" name="Using_the_LiveConnect_classes_with_the_JDK">JDK での LiveConnect クラスの使用</h3>

<p>LiveConnect クラスにアクセスするには、次のどちらかの方法で JDK コンパイラの <code>CLASSPATH</code> に .jar または .zip ファイルを配置します:</p>

<ul>
 <li><code>CLASSPATH</code> 環境変数を作成し、.jar または .zip ファイルのパスと名前を指定します。</li>
 <li>コンパイル時に <code>-classpath</code> コマンドラインパラメータを用いて .jar または .zip ファイルの場所を指定する。</li>
</ul>

<p>Windows NT では、コントロールパネルのシステムアイコンをダブルクリックし、<code>CLASSPATH</code> という名前のユーザ環境変数を作成し、それに次のような値を設定することで環境変数を作成できます:</p>

<pre class="eval">C:\Program Files\Java\jre1.4.1\lib\plugin.jar
</pre>

<p><code>CLASSPATH</code> についての詳細は Sun の JDK に関する資料をご覧ください。</p>

<p><strong>注意:</strong> Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために JavaScript ランタイムエンジンが引数の値を適当なデータ型に変換します。詳細は  をご覧ください。</p>

<h3 id="Using_the_LiveConnect_Classes" name="Using_the_LiveConnect_Classes">LiveConnect クラスの使用</h3>

<p>すべての JavaScript オブジェクトは、Java コード内では <code>netscape.javascript.JSObject</code> のインスタンスとして現れます。Java コード内でメソッドを呼び出すときに、その引数として JavaScriptのオブジェクトを渡すことができます。そうするためには、そのメソッドの対応する仮パラメータを <code>JSObject</code> 型で定義しなければなりません。</p>

<p>さらに、Java コード内で JavaScript のオブジェクトを使用するたびに、<code>netscape.javascript.JSException</code> 型の例外を処理する <code>try...catch</code> 文の内側で、その JavaScript オブジェクトを呼び出すようにしてください。こうすることで <code>JSException</code> 型の例外として Java で現れる、JavaScript コードの実行におけるエラーを Java コードで処理できるようになります。</p>

<h4 id="Accessing_JavaScript_with_JSObject" name="Accessing_JavaScript_with_JSObject">JSObject を用いた JavaScript へのアクセス</h4>

<p>例えば、<code>JavaDog</code> という Java のクラスを使用するとします。次のコードで示すように、<code>JavaDog</code> コンストラクタは JavaScript のオブジェクトである <code>jsDog</code> を引数としてとります。このオブジェクトは <code>JSObject</code> 型として定義されています:</p>

<pre class="brush: java">import netscape.javascript.*;

public class JavaDog{
    public String dogBreed;
    public String dogColor;
    public String dogSex;

    // クラスコンストラクタの定義
    public JavaDog(JSObject jsDog){
        // ここで try...catch を使用して JSExceptions を処理できるようにする
        this.dogBreed = (String)jsDog.getMember("breed");
        this.dogColor = (String)jsDog.getMember("color");
        this.dogSex = (String)jsDog.getMember("sex");
    }
}
</pre>

<p><code>JSObject</code><code>getMember</code> メソッドは、JavaScript のオブジェクトのプロパティにアクセスするために使用するものです。この例では JavaScript のプロパティである <code>jsDog.breed</code> の値を Java のデータメンバである <code>JavaDog.dogBreed</code> に代入するために、<code>getMember</code> を使用しています。</p>

<p><strong>注意:</strong> より現実的な例では <code>try...catch</code> 文の内側で <code>getMember</code> を呼び出し、<code>JSException</code> 型のエラーを処理できるようにします。詳細は、Java での JavaScript の例外処理を参照してください。</p>

<p><code>getMember</code> の動作をさらに知るために、JavaScript の <code>Dog</code> オブジェクトを作成し、その定義を見てみます:</p>

<pre class="brush: js">function Dog(breed,color,sex){
   this.breed = breed;
   this.color = color;
   this.sex = sex;
}
</pre>

<p><code>Dog</code> の JavaScript のインスタンスである <code>gabby</code> は、次のようにして作ることができます:</p>

<pre class="brush: js">var gabby = new Dog("lab", "chocolate", "female");
</pre>

<p><code>gabby.color</code> を評価すると、それが "chocolate" という値を持っていることがわかります。ここで次のように <code>gabby</code> オブジェクトをコンストラクタに渡し、JavaScript コードで <code>JavaDog</code> のインスタンスを作成することにします:</p>

<pre class="brush: js">var javaDog = new Packages.JavaDog(gabby);
</pre>

<p><code>javaDog.dogColor</code> を評価すると、それも "chocolate" という値を持っていることがわかります。これは Java のコンストラクタ内の <code>getMember</code> メソッドが、<code>gabby.color</code> の値を <code>dogColor</code> に代入するからです。</p>

<h4 id="Handling_JavaScript_Exceptions_in_Java" name="Handling_JavaScript_Exceptions_in_Java">Java での JavaScript の例外処理</h4>

<p>実行時に Java からの JavaScript コードの呼び出しに失敗すると、例外が投げられます。Java から JavaScript コードを呼び出すときに、<code>try...catch</code> 文でこの例外を受け取ることができます。JavaScript の例外は、<code>netscape.javascript.JSException</code> のインスタンスとして Java コードから扱えます。</p>

<p><code>JSException</code> は JavaScript が投げるあらゆる種類の例外に対応する、Java のラッパです。<code>JSObject</code> のインスタンスが JavaScript のオブジェクトのラッパであるのと同じようなものです。Java で JavaScript コードを評価するときは <code>JSException</code> を使用してください。</p>

<p>Java で JavaScript コードを評価する際、次の状況でランタイムエラーが発生します:</p>

<ul>
 <li>JavaScript コンパイルエラーまたは 実行時に生じた 他のエラーにより、JavaScript コードが評価されません。JavaScript インタプリタは、<code>JSException</code> のインスタンスに変換されるエラーメッセージを生成します。</li>
 <li>Java は正常に JavaScript のコードを評価しましたが、処理方法が定かでない <code>throw</code> 文をJavaScript コードが実行します。JavaScript は、<code>JSException</code> のインスタンスとしてラップされる例外を投げます。Java でこの例外のラップを解くには、<code>JSException</code><code>getWrappedException</code> メソッドを使用します。</li>
</ul>

<p>例えば、Java のオブジェクトである <code>jsCode</code> が自身に渡される文字列 <code>eTest</code> を評価するとします。次のようなエラー処理を実行することで、評価が原因で発生するどちらの種類のランタイムエラーにも対応できます:</p>

<pre class="brush: java">import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class eTest {
    public static Object doit(JSObject obj, String jsCode) {
        try {
            obj.eval(jsCode);
        } catch (JSException e) {
            if (e.getWrappedException() == null)
                return e;
            return e.getWrappedException();
        }
        return null;
    }
}
</pre>

<p>この例では、渡された文字列 <code>jsCode</code><code>try</code> ブロック内のコードが評価しようとします。文字列 "<code>myFunction()</code>" を <code>jsCode</code> の値として渡すとします。<code>myFunction</code> が JavaScript の関数として定義されていない場合、JavaScript インタプリタは <code>jsCode</code> を評価できません。インタプリタはエラーメッセージを生成し、Java のハンドラがそのメッセージを受け取り、<code>doit</code> メソッドは <code>netscape.javascript.JSException</code> のインスタンスを返します。</p>

<p>しかし、次のように <code>myFunction</code> が JavaScript で定義されているとします:</p>

<pre class="brush: js">function myFunction() {
   try {
      if (theCondition == true) {
         return "Everything's ok";
      } else {
         throw "JavaScript error occurred";
      }
   } catch (e) {
      if (canHandle == true) {
         handleIt();
      } else {
         throw e;
      }
   }
}
</pre>

<p><code>theCondition</code> が false であれば、関数は例外を投げます。その例外は JavaScript コードで受け取られ、さらに <code>canHandle</code> が true の場合に JavaScript はそれを処理します。<code>canHandle</code> false がならばその例外が再び投げられ、Java のハンドラがそれを受け取り、 <code>doit</code> メソッドが次の Java の文字列を返します:</p>

<pre>JavaScript error occurred
</pre>

<p>JavaScript の例外についての詳細情報は<a href="/ja/docs/JavaScript/Guide/Statements#Exception_Handling_Statements" title="ja/docs/JavaScript/Guide/Statements#Exception Handling Statements">例外処理文</a>を参照してください。</p>

<h4 id="Backward_Compatibility" name="Backward_Compatibility">後方互換性</h4>

<p>JavaScript 1.3 以前のバージョンでは、<code>JSException</code> クラスには省略可能な文字列引数をとる 3 つの public タイプのコンストラクタがありました。この文字列引数は、詳細なメッセージやその例外に対する他の情報を指定するものです。<code>getWrappedException</code> メソッドは使用できませんでした。</p>

<p>次のような <code>try...catch</code> 文を使用することで、JavaScript 1.3 以前のバージョンで LiveConnect の例外を処理できます:</p>

<pre class="brush: js">try {
   global.eval("foo.bar = 999;");
} catch (Exception e) {
   if (e instanceof JSException) {
      jsCodeFailed();
   } else {
      otherCodeFailed();
   }
}
</pre>

<p>この例では <code>foo</code> が定義されていないと <code>eval</code> 文が失敗します。<code>try</code> ブロックの <code>eval</code> 文が <code>JSException</code> を投げると、<code>catch</code> ブロックが <code>jsCodeFailed</code> メソッドを実行します。<code>try</code> ブロックがそれ以外のエラーを投げると、<code>otherCodeFailed</code> メソッドが実行されます。</p>

<h2 id="Data_Type_Conversions" name="Data_Type_Conversions">データ型変換</h2>

<p>Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために、JavaScript ランタイムエンジンが引数の値を適切なデータ型に変換します。この変換について以下のセクションで説明します:</p>

<ul>
 <li>JavaScript から Java への変換</li>
 <li>Java からJavaScript への変換</li>
</ul>

<h3 id="JavaScript_to_Java_Conversions" name="JavaScript_to_Java_Conversions">JavaScript から Java への変換</h3>

<p>JavaScript から Java のメソッドを呼び出してパラメータを渡す際、渡すパラメータのデータ型は以下のセクションで説明するルールによって変換されます:</p>

<ul>
 <li>数値</li>
 <li>真偽値</li>
 <li>文字列値</li>
 <li>undefined 値</li>
 <li>null 値</li>
 <li>JavaArray および JavaObject オブジェクト</li>
 <li>JavaClass オブジェクト</li>
 <li>その他の JavaScript オブジェクト</li>
</ul>

<p><code>netscape.javascript.JSObject</code> メソッドの戻り値は常に <code>java.lang.Object</code> のインスタンスに変換されます。このような戻り値の変換ルールもここで説明します。</p>

<p>例えば <code>JSObject.eval</code> が JavaScript の数値を返すのであれば、この数値を <code>java.lang.Object</code> のインスタンスに変換するルールは数値に記載されています。</p>

<h4 id="Number_Values" name="Number_Values">数値</h4>

<p>Java のメソッドに JavaScript の数値型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>double</td>
   <td>
    <ul>
     <li>そのままの値が、丸められたり絶対値や符号が損なわれることなく Java に渡されます。</li>
     <li><code>NaN</code><code>NaN</code> に変換されます。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>java.lang.Double<br>
    java.lang.Object</td>
   <td><code>java.lang.Double</code> の新しいインスタンスが作成され、そのままの値が、丸められたり絶対値や符号が損なわれることなく Java に渡されます。</td>
  </tr>
  <tr>
   <td>float</td>
   <td>
    <ul>
     <li>値は float 精度に丸められます。</li>
     <li>大きすぎまたは小さすぎて表現できない値は、正の無限大または負の無限大に丸められます。</li>
     <li><code>NaN</code><code>NaN</code> に変換されます。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    int<br>
    long<br>
    short</td>
   <td>
    <ul>
     <li>値は負の無限大方向に丸められます。</li>
     <li>大きすぎまたは小さすぎて表現できない値は、ランタイムエラーになります。</li>
     <li><code>NaN</code> は変換されずにランタイムエラーになります。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td><code>java.lang.String</code></td>
   <td>値は文字列に変換されます。例えば:
    <ul>
     <li>237 は "237" になります。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>
    <ul>
     <li>0 および <code>NaN</code> は false に変換されます。</li>
     <li>その他の値は true に変換されます。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の数値をパラメータとして渡すと、その数値は文字列に変換されます。<code>equals()</code> メソッドを使用すると、この変換結果と他の文字列を比較できます。</p>

<h4 id="Boolean_Values" name="Boolean_Values">真偽値</h4>

<p>Java のメソッドに JavaScript の真偽値型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>boolean</td>
   <td>すべての値は、Java で対応するものに直接変換されます。</td>
  </tr>
  <tr>
   <td><code>java.lang.Boolean</code><br>
    <code>java.lang.Object</code></td>
   <td><code>java.lang.Boolean</code> の新しいインスタンスが作成されます。同一のプリミティブ値に対して 1 つのインスタンスではなく、各パラメータについて新しいインスタンスが作成されます。</td>
  </tr>
  <tr>
   <td><code>java.lang.String</code></td>
   <td>値は文字列に変換されます。例えば:
    <ul>
     <li>true は "true" になります。</li>
     <li>false は "false" になります。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    double<br>
    float<br>
    int<br>
    long<br>
    short</td>
   <td>
    <ul>
     <li>true は 1 になります。</li>
     <li>false は 0 になります。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の真偽値をパラメータとして渡すと、その真偽値は文字列に変換されます。== 演算子を使用すると、この変換結果と他の文字列を比較できます。</p>

<h4 id="String_Values" name="String_Values">文字列値</h4>

<p>Java のメソッドに JavaScript の文字列型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>java.lang.String</code><br>
    <code>java.lang.Object</code></td>
   <td>JavaScript 1.4:
    <ul>
     <li>JavaScript の文字列は、Unicode 値で <code>java.lang.String</code> のインスタンスに変換されます。</li>
    </ul>

    <p>JavaScript 1.3 以前:</p>

    <ul>
     <li>JavaScript の文字列は、ASCII 値で <code>java.lang.String</code> のインスタンスに変換されます。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>byte<br>
    double<br>
    float<br>
    int<br>
    long<br>
    short</td>
   <td>すべての値は、ECMA-262 に記載に従って数値に変換されます。JavaScript の文字列値は ECMA-262 に記載されたルールに従って数値に変換されます。</td>
  </tr>
  <tr>
   <td>char</td>
   <td>JavaScript 1.4:
    <ul>
     <li>1 文字の文字列は、Unicode 文字に変換されます。</li>
     <li>他のすべての値は数値に変換されます。</li>
    </ul>

    <p>JavaScript 1.3 以前:</p>

    <ul>
     <li>すべての値が数値に変換されます。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>
    <ul>
     <li>空文字列は false になります。</li>
     <li>他のすべての値は true になります。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<h4 id="Undefined_Values" name="Undefined_Values">undefined 値</h4>

<p>Java のメソッドに JavaScript の undefined 値をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>java.lang.String</code><br>
    <code>java.lang.Object</code></td>
   <td>値は java.lang.String のインスタンスに変換され、インスタンスの値は文字列 "undefined" になります。</td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>値は false になります。</td>
  </tr>
  <tr>
   <td>double<br>
    float</td>
   <td>値は <code>NaN</code> になります。</td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    int<br>
    long<br>
    short</td>
   <td>値は 0 になります。</td>
  </tr>
 </tbody>
</table>

<p>undefined 値の変換は JavaScript 1.3 以降でのみ可能です。それより古いバージョンでは、undefined 値がサポートされていません。</p>

<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の undefined 値をパラメータとして渡すと、その undefined 値は文字列に変換されます。== 演算子を使用すると、この変換結果と他の文字列を比較できます。</p>

<h4 id="Null_Values" name="Null_Values">null 値</h4>

<p>Java のメソッドに JavaScript の null 値をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>あらゆるクラス<br>
    あらゆるインタフェースの種類</td>
   <td>値は null になります。</td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    double<br>
    float<br>
    int<br>
    long<br>
    short</td>
   <td>値は 0 になります。</td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>値は false になります。</td>
  </tr>
 </tbody>
</table>

<h4 id="JavaArray_and_JavaObject_objects" name="JavaArray_and_JavaObject_objects">JavaArray および JavaObject オブジェクト</h4>

<p>ほとんどの場合、Java のメソッドに JavaScript の <code>JavaArray</code> または <code>JavaObject</code> オブジェクトをパラメータとして渡すと、Java は単にそのオブジェクトのラップを解きます。そうでない場合は、Java は次の表で示すルールに従ってそのオブジェクトを別のデータ型に変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>ラップが解かれたオブジェクトと代入互換性のある、あらゆるインタフェースまたはクラス</td>
   <td>オブジェクトのラップが解かれます。</td>
  </tr>
  <tr>
   <td><code>java.lang.String</code></td>
   <td>オブジェクトのラップが解かれ、ラップが解かれた Java オブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    double<br>
    float<br>
    int<br>
    long<br>
    short</td>
   <td>オブジェクトのラップが解かれ、次の状況のどちらかが起こります:
    <ul>
     <li>ラップが解かれた Java のオブジェクトに <code>doubleValue</code> メソッドがあれば、<code>JavaArray</code> または <code>JavaObject</code> はこのメソッドが返す値に変換されます。</li>
     <li>ラップが解かれた Java オブジェクトに <code>doubleValue</code> メソッドがなければ、エラーが発生します。</li>
    </ul>
   </td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:
    <ul>
     <li>オブジェクトが null ならば、false に変換されます。</li>
     <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li>
    </ul>

    <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p>

    <ul>
     <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li>
     <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<p>ラップが解かれたオブジェクトが Java のパラメータ型のインスタンスであれば、インタフェースまたはクラスが、ラップが解かれたオブジェクトと代入互換性があるということです。つまり、次の文は必ず true を返します:</p>

<pre class="brush: js">unwrappedObject instanceof parameterType;
</pre>

<h4 id="JavaClass_objects" name="JavaClass_objects">JavaClass オブジェクト</h4>

<p>Java のメソッドに JavaScript の <code>JavaClass</code> オブジェクトをパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>java.lang.Class</code></td>
   <td>オブジェクトのラップが解かれます。</td>
  </tr>
  <tr>
   <td><code>netscape.javascript.JSObject</code><br>
    <code>java.lang.Object</code></td>
   <td><code>JavaClass</code> オブジェクトが <code>netscape.javascript.JSObject</code> の新しいインスタンス内にラップされます。</td>
  </tr>
  <tr>
   <td><code>java.lang.String</code></td>
   <td>オブジェクトのラップが解かれ、ラップが解かれた Java オブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:
    <ul>
     <li>オブジェクトが null ならば、false に変換されます。</li>
     <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li>
    </ul>

    <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p>

    <ul>
     <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li>
     <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<h4 id="Other_JavaScript_objects" name="Other_JavaScript_objects">その他の JavaScript のオブジェクト</h4>

<p>Java のメソッドに JavaScript のその他のオブジェクトをパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Java のパラメータ型</th>
   <th scope="col">変換ルール</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>netscape.javascript.JSObject</code><br>
    <code>java.lang.Object</code></td>
   <td>オブジェクトは <code>netscape.javascript.JSObject</code> の新しいインスタンス内にラップされます。</td>
  </tr>
  <tr>
   <td><code>java.lang.String</code></td>
   <td>オブジェクトのラップが解かれ、ラップが解かれたオブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td>
  </tr>
  <tr>
   <td>byte<br>
    char<br>
    double<br>
    float<br>
    int<br>
    long<br>
    short</td>
   <td>オブジェクトは、ECMA-262 に記載された <code>ToPrimitive</code> 演算子のロジックを使用して値に変換されます。この演算子で使用される <em>PreferredType</em> ヒントは Number です。</td>
  </tr>
  <tr>
   <td>boolean</td>
   <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:
    <ul>
     <li>オブジェクトが null ならば、false に変換されます。</li>
     <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li>
    </ul>

    <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p>

    <ul>
     <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li>
     <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li>
    </ul>
   </td>
  </tr>
 </tbody>
</table>

<h3 id="Java_to_JavaScript_Conversions" name="Java_to_JavaScript_Conversions">Java から JavaScript への変換</h3>

<p>Java から JavaScript に渡された値は、次のように変換されます:</p>

<ul>
 <li>Java の byte、char、short、int、long、float および double は、JavaScript の数値に変換されます。</li>
 <li>Java の boolean は、JavaScript の真偽値に変換されます。</li>
 <li>クラス <code>netscape.javascript.JSObject</code> のオブジェクトは、元の JavaScript のオブジェクトに変換されます。</li>
 <li>Java の配列は JavaScript の擬似的な Array オブジェクトに変換されます。このオブジェクトは JavaScript の <code>Array</code> オブジェクトと全く同じような挙動をとります。つまり、<code>arrayName[index]</code> (<code>index</code> は整数) という構文でそれにアクセスでき、その長さを <code>arrayName.length</code> で判断できます。</li>
 <li>Java のそれ以外オブジェクトは、JavaScript のラッパに変換されます。このラッパを通じて Java のオブジェクトのメソッドやフィールドにアクセスできます:
  <ul>
   <li>このラッパから文字列への変換では、元のオブジェクトで <code>toString</code> メソッドが呼び出されます。</li>
   <li>数値への変換では、可能であれば <code>doubleValue</code> メソッドが呼び出され、そうでなければ失敗します。</li>
   <li>JavaScript 1.3 以降の真偽値への変換では、そのオブジェクトが null であれば false が、そうでなければ true を返します。</li>
   <li>JavaScript 1.2 以前の真偽値への変換では、可能であれば <code>booleanValue</code> メソッドが呼び出され、そうでなければ失敗します。</li>
  </ul>
 </li>
</ul>

<p>java.lang.Double および java.lang.Integer のインスタンスは、JavaScript の数値ではなく JavaScript のオブジェクトに変換されることに注意してください。同様に java.lang.String のインスタンスも、JavaScript の文字列ではなく JavaScript のオブジェクトに変換されます。</p>

<p>Java の <code>String</code> オブジェクトも、JavaScript のラッパに相当します。JavaScript の文字列を必要とする JavaScript のメソッドを、このラッパを渡して呼び出すとエラーになります。そうではなく、次のようにラッパに空文字列を付加することで、ラッパを JavaScript の文字列に変換してください:</p>

<pre class="brush: js">var JavaString = JavaObj.methodThatReturnsAString();
var JavaScriptString = JavaString + "";</pre>