javaによるユーザ定義関数を定義するにはFunctionImplementationインタフェースを実装したオブジェクトを 作成し、defineUserFunctionメソッドで登録します。
(defineUserFunctionメソッド)defineUserFunction(FunctionImplementation func);
FunctionImplementationインタフェースは、1個で複数の関数を定義できる インタフェースです。 以下のメソッドをサポートしている必要があります。
(FunctionImplementationインタフェース)メソッド | 意味 |
---|---|
String[] names() | このクラスで定義されている関数名の配列を返す。 |
int numberOfArgs(String name) | 指定した名前の関数の引数の個数を返す。 |
boolean supports(String name) | 指定した名前がこのクラスで定義されている関数名であるときtrueを返す。 |
BigDecimal value(String name, BigDecimal[] args) | 指定した名前の関数のBigDecimalの関数実行結果を返す。 |
double value(String name, double[] args) | 指定した名前の関数のdoubleの関数実行結果を返す。 |
他のメソッド(names, numberOfArgs, value)は全てFunctionAdaptorが上記の 実装から「うまくやって」くれます。
(FunctionAdaptorクラス使用例)//ユーザ関数実装のサンプル class UserFuncSample extends FunctionAdaptor{ //円周の計算 double circle(double r){ return 2.0 * r * Math.PI; } } //メインのクラス class MainClass { public static void main(String[] args) { try{ FormulaEvaluator fe=new FormulaEvaluator(); fe.defineUserFunction(new UserFuncSample()); //ユーザ定義関数の定義 System.out.println(fe.dEvaluate("circle(2.0)"));//ユーザ定義関数の呼出 } catch (Exception e){ e.printStackTrace(); } } }なお、システム定義関数もFunctionAdaptorを拡張してプログラムしていますので ソースコードを参考にしてください。(src/com/sanpudo/formula/SystemFunctions.java)
同じクラスで同名の関数でdouble, BigDecimalの両方を必ずサポートしている必要は ありません。しかし、もし両方サポートする場合は引数の個数が 同じでなければなりません。制約に違反すると例外がスローされます。
異なるクラスで同名の関数を登録した場合は、後に登録した方が優先されます。
FunctionImplementationインタフェースを実装したオブジェクトを、 インスタンスを作成するのではなく、クラス名を指定してロードする事も 可能です。loadUserFunctionメソッドを使います。インスタンスの生成は このメソッドの中で行われます。 ロードされるクラスは引数無しのコンストラクタをサポートしている必要が あり、また、CLASSPATHの通った場所にある必要があります。
(loadUserFunctionメソッド)defineUserFunction(String クラスパスの通ったクラス名);(loadUserFunctionメソッドの例)
formulaEvaluator.defineUserFunction("com.sanpudo.UerFuncSample");このメソッドがサポートされていると言う事は、メインのプログラムを コンパイルしなおす必要なく、外部で準備したユーザ定義関数を 実行時に名前を指定してロードするプログラムが作れる事を意味しています。