跳到主要内容

OpcUaVariant

OpcUaVariant 是 OPC UA 的通用值容器, 覆盖 OPC UA 全部内置数据类型. SDK 用它在 Java 与 native 之间传值.

实现 AutoCloseable — 持有 native handle, 必须 close.

配套

公共方法

类别属性类型访问说明
状态handle()PointerR内部 native handle (调试用)
getDataType()Enums.BuiltinTypeR内置数据类型
构造 / 设值setBoolean / setSByte / setByte / setInt16 / setUInt16 / setInt32 / setUInt32 / setInt64 / setFloat / setDouble / setString / setDateTimeOpcUaVariant (this)W链式设值, 返回自身
取值asBoolean()BooleanR类型不匹配返回 null
asInt32()IntegerR类型不匹配返回 null
asUInt32()LongR用 Long 容纳无符号
asInt64()LongR类型不匹配返回 null
asDouble()DoubleR类型不匹配返回 null
asString()StringR类型不匹配返回 null
asFileTime()longRDateTime 取 Windows FileTime, 0 = 空
tryGet 风格tryGetBoolean(IntByReference)booleanR成功返回 true, 输出存到 IntByReference
tryGetInt32 / tryGetUInt32 / tryGetInt64 / tryGetDoublebooleanR同上, 输出对应类型 ByReference
释放close()void释放 native 内存 (owns=true 时)

构造与设值 (链式)

new OpcUaVariant().setBoolean(true)            // Boolean
new OpcUaVariant().setSByte((byte) -1) // SByte
new OpcUaVariant().setByte(255) // Byte
new OpcUaVariant().setInt16((short) 42) // Int16
new OpcUaVariant().setUInt16(42) // UInt16
new OpcUaVariant().setInt32(42) // Int32
new OpcUaVariant().setUInt32(42) // UInt32
new OpcUaVariant().setInt64(42L) // Int64
new OpcUaVariant().setFloat(3.14f) // Float
new OpcUaVariant().setDouble(3.14) // Double
new OpcUaVariant().setString("hello") // String
new OpcUaVariant().setDateTime(fileTimeLong) // DateTime (Windows FileTime)

读取 (强类型)

try (OpcUaDataValue dv = ua.read("ns=2;s=T1")) {
OpcUaVariant v = dv.variant(); // 不持有, 不要 close
Double d = v.asDouble(); // null = 类型不匹配
Integer i = v.asInt32();
String s = v.asString();
Boolean b = v.asBoolean();
long ft = v.asFileTime(); // DateTime
}

类型不匹配返回 null (Java SDK 风格), 不抛异常 — 上层显式 null 判断.


tryGet (out 风格)

import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.DoubleByReference;

OpcUaVariant v = dv.variant();

IntByReference outI = new IntByReference();
if (v.tryGetInt32(outI)) {
int n = outI.getValue();
}

DoubleByReference outD = new DoubleByReference();
if (v.tryGetDouble(outD)) {
double x = outD.getValue();
}

DateTime ↔ Instant

import java.time.Instant;

// FileTime → Instant
long ft = v.asFileTime();
Instant t = (ft > 0)
? Instant.ofEpochMilli((ft - 116444736000000000L) / 10000L)
: Instant.now();

// Instant → FileTime
long ft2 = t.toEpochMilli() * 10000L + 116444736000000000L;
v.setDateTime(ft2);

toString

OpcUaVariant.toString() 按 DataType 智能格式化:

DataType输出示例
Double / Float3.14
Int32 / UInt3242
Stringhello
DateTimeft=132456... (FileTime raw, 自己转 Instant 显示)
其他<TypeName>

内存所有权

OpcUaVariant 包装 native handle, 实现 AutoCloseable:

来源owns是否要 close
new OpcUaVariant() 构造true
ua.read(...) 间接持有 (经 OpcUaDataValue)由 OpcUaDataValue 接管
ua.call(...) 返回的 outputstrue (逐项 close)
OpcUaDataValue.variant() 返回false否 (随 DataValue 一起释放)

最佳实践:

try (OpcUaVariant v = new OpcUaVariant().setDouble(42.0)) {
ua.write("ns=2;s=X", v);
} // 自动 close
漏 close 后果

漏 close 会泄漏 native 内存 (定时跑 100k+ 次会涨内存). 永远用 try-with-resources 包构造的 OpcUaVariant.


BuiltinType 完整清单 (Enums.BuiltinType)

Null (0), Boolean (1), SByte (2), Byte (3),
Int16 (4), UInt16 (5), Int32 (6), UInt32 (7), Int64 (8), UInt64 (9),
Float (10), Double (11), String (12), DateTime (13), Guid (14),
ByteString (15), XmlElement (16), NodeId (17), ExpandedNodeId (18),
StatusCode (19), QualifiedName (20), LocalizedText (21),
ExtensionObject (22), DataValue (23), Variant (24), DiagnosticInfo (25)

数组类型

当前 Java SDK Variant 暴露的 setXxx/asXxx 主要面向标量. 数组场景请通过底层 native 接口或后续版本扩展.

ExtensionObject (复杂结构)

OPC UA Server 自定义 Struct DataType 通过 ExtensionObject 包装. 当前 SDK 提供基础 ExtensionObject 容器, 完整 schema 解析在后续版本.

下一步