A.4.2 如何在 Octave 中使用 Java

函数 javaObject 用于创建 Java 对象。实际上,它会调用指定名称的类的公有构造函数,并传入给定的参数。

以下示例展示了如何调用内置 Java 类 java.math.BigDecimal 的构造函数 BigDecimal(double)BigDecimal(String)

javaObject ("java.math.BigDecimal",  1.001 );
javaObject ("java.math.BigDecimal", "1.001");

请注意,Octave 类型 double 的参数会隐式转换为 Java 类型 double,而 Octave 类型(或字符数组)char 会转换为 Java 类型 String。由 javaObject 创建的 Java 对象永远不会自动转换为 Octave 类型,而是保持为 Java 对象。它可以赋值给 Octave 变量。

a = 1.001;
b = javaObject ("java.math.BigDecimal", a);

使用 isjava 可以检查一个变量是否为 Java 对象,同时也可以确定其类。接续前面的示例:

isjava (a)
⇒   ans = 0
class (a)
⇒   ans = double
isjava (b)
⇒   ans = 1
class (b)
⇒   ans = java.math.BigDecimal

上述示例也可以全部使用 Java 对象来完成:

a = javaObject ("java.lang.Double", 1.001);
b = javaObject ("java.math.BigDecimal", a);

isjava (a)
⇒   ans = 1
class (a)
⇒   ans = java.lang.Double
isjava (b)
⇒   ans = 1
class (b)
⇒   ans = java.math.BigDecimal

可以看到,即使是 java.lang.Double 对象,当通过 javaObject 创建时,也不会转换为 Octave 的 double 类型。但是,如果 Java 类 java.lang.Doubledouble 作为方法(或构造函数)的参数时,可能会产生歧义。在这种情况下,它们可以根据上下文相互转换。

通过 javaObject 可以创建除数组之外的所有类型的 Java 对象。而数组则需要通过 javaArray 来创建。

可以使用 Java 语法在 Java 对象上调用公有成员方法:

a.toString
⇒   ans = 1.001
b.toString
⇒   ans = 1.000999999999999889865...

第二个结果可能令人惊讶,但这只是因为 1.001 无法精确表示为 double 类型(由于舍入误差)。请注意,与 Java 不同,在 Octave 中,无参方法可以带括号 () 调用,也可以不带括号调用。

目前,在 Octave 中无法使用类似 Java 的语法来调用静态方法。相反,必须使用函数 javaMethod,如下例所示:

java.math.BigDecimal.valueOf(1.001);                    # 不可行
javaMethod ("valueOf", "java.math.BigDecimal", 1.001);  # 变通方法

如前所述,方法和构造函数的参数会在 Octave 和 Java 类型之间自动转换(在适当的情况下)。对于函数(方法)而言,返回值也是如此;但对于构造函数,返回值不会自动转换。

也可以使用 Java 语法从 Octave 中访问 Java 对象的公有字段,但静态字段有限制:

java.math.BigDecimal.ONE;                  # 不可行
java_get ("java.math.BigDecimal", "ONE");  # 变通方法

相应地,可以使用 java_set 来设置字段的值。请注意,只有 Java 的公有字段才能从 Octave 内部访问。

以下示例表明,在 Octave 中,空括号 [] 代表 Java 的 null 值,并展示了 Java 异常的表示方式。

javaObject ("java.math.BigDecimal", []);
⇒   error: [java] java.lang.NullPointerException

不建议使用空括号 [] 来表示 Java 的 null 值,因为 null 没有类型,而 [] 具有 double 类型。

在 Octave 中,可以通过列出 Java 对象的公有字段和方法(静态或非静态)来提供有限的 Java 反射功能。

fieldnames (<Java 对象>)
methods (<Java 对象>)

最后,展示一个如何在 Octave 内部访问堆栈跟踪的示例。其中函数 debug_java 用于设置和获取当前的调试状态。在调试模式下,将显示 Java 错误和堆栈跟踪信息。

debug_java (true)  # 使用 "false" 可省略堆栈跟踪的显示
debug_java ()
⇒   ans = 1
javaObject ("java.math.BigDecimal", "1") ...
  .divide (javaObject ("java.math.BigDecimal", "0"))

版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-4