入門 - 第2ステップ
Java Scilab バインディングを使用するには?
説明
このチュートリアルは, 第1ステップの続きです.
例 3: Scilabvで Java オブジェクトを使用する
この例では,より高度に抽象化された一連のJavaオブジェクトを 定義します. 次に, Javaスクリプト言語の一種としてScilabを使用して これらのオブジェクトに様々な操作を行います. 以下の様なJavaの広範な機能を紹介します; staticメソッド (Factory construct), Enums, 簡単なポリモーフィズム, メンバ/メソッドのスコープ.
この広範な機能は,簡単な家を記述する7つの簡単なクラスにより示されます;
// House.java という名前で保存 package com.foo; import java.util.Arrays; import java.util.LinkendList; import java.util.List; public class House { private Color color; private Door door; private List<IWindow> windows = new LinkendList<IWindow>(); public House(Color color, Door door, IWindow... windows) { this.color = color; this.door = door; this.windows.addAll(Arrays.asList(windows)); } public void repaint() { swapDoorHouseColor(); } private void swapDoorHouseColor() { Color doorColor = door.getColor(); door.repaint(color); color = doorColor; } public void addWindow(IWindow window) { windows.add(window); } public void replaceDoor(Door newDoor) { this.door = newDoor; } @Override public String toString() { return String.format( "This is a house painted in %s, has a %s door, and %d windows", color.getDescr(), door.getColor().getDescr(), windows.size()); } }
package com.foo; public class HouseFactory { public static House basicHouse() { Door door = new Door(Color.WHITE); IWindow window = new RectangularWindow(2, 0.8); return new House(Color.WHITE, door, window); } public static House flashyHouse() { Door door = new Door(Color.random()); IWindow window = new CircularWindow(1.2); return new House(Color.random(), door, window); } }
package com.foo; import java.util.Random; public enum Color { BLACK("black"), BLUE("blue"), BROWN("brown"), GREEN("green"), ORANGE("orange"), RED("red"), WHITE("white"), YELLOW("yellow"); public String descr; private Color(String s) { descr = s; } public String getDescr() { return descr; } public static Color random() { Color[] allColors = values(); return allColors[new Random().nextInt(values().length)]; } }
package com.foo; public class Door { private Color color; public Door(Color color) { this.color = color; } public Color getColor() { return color; } public void repaint(Color newColor) { color = newColor; } }
package com.foo; public interface IWindow { double getWindowArea(); }
package com.foo; public class RectangularWindow implements IWindow { double length; double width; public RectangularWindow(double length, double width) { this.length = length; this.width = width; } public double getWindowArea() { return length * width; } }
package com.foo; public class CircularWindow implements IWindow { double radius; public CircularWindow(double radius) { this.radius = radius; } public double getWindowArea() { return Math.PI * radius * radius; } }
// この例はScilabディストリビューションに含まれます. directory=SCI+"/modules/external_objects_java/examples/com/foo/" // これらを全てコンパイルします jcompile(ls(directory + "/*.java"))
まず, 基本となるfactory houseを構築しましょう. このため, HouseFactory をインポートし, 静的メソッドbasicHouse() を呼び出す必要があります.
--> jimport("com.foo.HouseFactory") --> house = HouseFactory.basicHouse() house = This is a house painted in white, has a white door, and 1 windows
これは, 静的メソッドをJavaと同様にコールできることを示します. これは, "jinvoke(HouseFactory, 'basicHouse')" と等価であることも 頭に入れておいてください. オブジェクトのメッセージも以下のように交換できます:
com.foo.House@ae8022 To This is a house painted in white, has a white door, and 1 windows
toString
は,この表現を生成する際に使用されます.
jgetclassname を呼び出すことにより,
この場合も Houseオブジェクトの実際の型(クラス)を取得できます.
--> jgetclassname(house) ans = com.foo.House
addWindow(IWindow)
関数により家に追加します.
IWindow
は窓に関する抽象化された説明で, 直接インスタンス化することはできません.
しかし, 構築時に以下の2種類の実装が利用可能です; RectangularWindow
および
CircularWindow
. この家は, factory で
RectangularWindow
を1つ付けているため,
新たにCircularWindow
を作成してみましょう.
--> jimport("com.foo.IWindow") --> IWindow.new() !--error 999 Method invocation: An error occurred: Exception when calling Java method : No such constructor in the class com.foo.IWindow. --> jimport("com.foo.CircularWindow") --> newWindow = CircularWindow.new(0.5) newWindow = com.foo.CircularWindow@3e389405 --> house.addWindow(newWindow); --> house house = This is a house painted in white, has a white door, and 2 windows
新しい窓が作成され, リファレンスが変数 "newWindow" に保存されました. 次に, この窓が変数をラップすることを必要とせずに家に追加されました. これは通常予想される動作です.最後に, 家が2つの窓を有することを表示します.
しかし, ドアが気に入らないため, ドアを変更してみましょう. ドアを作成するには, ドアの色を選ぶ必要があります. Color はJava Enum クラス型です. 前記と同様に, まず変数をインポートし,新規インスタンスを作成した後, 家のドアを交換します.
--> jimport("com.foo.Color") --> jimport("com.foo.Door") --> newDoor = Door.new(Color.RED) newDoor = com.foo.Door@54a5f709 --> house.replaceDoor(newDoor); --> house house = This is a house painted in white, has a red door, and 2 windows
Enum型の使用はクラスと同様に簡単です! これらのメソッドとメンバは同じ方針に基づいています:
--> c = Color.random() c = BLACK --> c = Color.random() c = BLUE --> c.getDescr() ans = blue
家に保持される窓のリストはIWindow
型
です. これにより, リストに追加できるのは通常は窓のみです.
これを確かめるため, ScilabでDoor
を
追加するとどうなるかを見てみましょう.
--> house.addWindow(newDoor); !--error 999 Method invocation: An error occurred: Exception when calling Java method : No method addWindow in the class com.foo.House or bad arguments type.
Java Reflectionを使用した場合と同様, JVM セキュリティ機構が,Javaポリモーフィズム規則に反することを防止するべく監視しています.
--> c.descr ans = blue --> house.door !--error 999 %_EObj_e: An error occurred: Exception when calling Java method : Invalid field door --> house.repaint(); --> house house = This is a house painted in red, has a white door, and 2 windows --> house.swapDoorHouseColor() !--error 999 %_EObj_e: An error occurred: Exception when calling Java method : Invalid field swapDoorHouseColor
結論として, JIMSパッケージは Java JNIインターフェイスをScilab上で隠蔽する役割を担っており, これにより,非常に簡単にかつ透過的にScilabでJavaライブラリを使用することが可能です. 全ての通常のJVM機能が存在し,Scilab構文は明確で直感的に使用できます.
ここまでで, ScilabとJavaライブラリを連携させ, Javaの全機能をScilabスクリプト環境で利用する 方法を理解できたはずです.
履歴
バージョン | 記述 |
5.5.0 | 関数が導入されました. 'JIMS'モジュールに基づきます. JIMSモジュールとの動作上の主な違いは, jautoUnwrapがデフォルトで 有効になっていることです. |
Report an issue | ||
<< 入門 - 第1ステップ | Java from Scilab | jallowClassReloading >> |