Table of Contents

Interface IJavaArray

Namespace
MASES.JCOBridge.C2JBridge.JVMInterop
Assembly
C2JBridge.dll

Interface for array objects, extends IJavaObjectBase

public interface IJavaArray : IJavaObjectBase, IDisposable, IEnumerable
Inherited Members
Extension Methods

Properties

Length

The array length

int Length { get; }

Property Value

int

Methods

Get(int)

Returns the element at the position in index

object Get(int index)

Parameters

index int

The index to get

Returns

object

The value at index

Get(int, int)

Returns a sub array at startIndex with a length of length

object Get(int startIndex, int length)

Parameters

startIndex int

The start index to get

length int

The number of elements to get

Returns

object

An object containing the sub-array values starting at startIndex with the specified length. The actual runtime type depends on the underlying JVM array element type.

Set(int, object)

Set the element at the position in index with the value in value

void Set(int index, object value)

Parameters

index int

The index to set

value object

The value to set at index

Set<T>(int, T[])

Set the elements in values starting from the position in startIndex

void Set<T>(int startIndex, T[] values)

Parameters

startIndex int

The start index to get

values T[]

The values to set starting from startIndex

Type Parameters

T

The element type of values. Supported types are native primitives (bool, byte, char, short, int, long, float, double), IJavaArray, and IJavaObject. Passing a type inconsistent with the actual JVM array element type results in undefined behaviour at runtime.

ToStream<T>(FileAccess, bool)

Returns a JCOBridgeStream<T> that wraps the native memory backing this IJavaArray instance, allowing it to be read or written as a standard .NET Stream.

JCOBridgeStream<T> ToStream<T>(FileAccess mode = FileAccess.Read, bool forceRawMemory = false) where T : unmanaged

Parameters

mode FileAccess

Specifies the intended access pattern for the returned stream. Use Read (default) for read-only access, Write or ReadWrite when modifications must be written back to the JVM array on Dispose().

forceRawMemory bool

When true, requests direct access to the JVM array memory without any intermediate copy. This option is only effective under a JCOBridge High Performance (HPA) license; with a standard license it is silently ignored. See the remarks section for the behaviour and constraints of each combination.

Returns

JCOBridgeStream<T>

A JCOBridgeStream<T> wrapping the native memory of this IJavaArray instance.

Type Parameters

T

The .NET primitive type corresponding to the element type of this IJavaArray. Supported types reflect the JVM primitive type system:

JVM type.NET type
booleanbool
bytebyte
shortshort
intint
longlong
floatfloat
doubledouble
charchar

Unsigned types (sbyte, ushort, uint, ulong) are not supported as they have no equivalent in the JVM type system. Passing an unsupported type throws NotSupportedException at runtime; passing a type inconsistent with the actual JVM array element type throws InvalidOperationException.

Remarks

Standard licenseforceRawMemory has no effect. The stream operates on a local copy of the JVM array data. This is the same cost already paid when the array is obtained via ToArray(), so no additional overhead is introduced. There are no constraints on JVM interaction or stream lifetime. Write-back to the JVM array is handled automatically on Dispose() when the stream was opened with write access and at least one write was performed.

HPA license — forceRawMemory = false. The JVM runtime may expose a direct pointer to the array storage or an internal copy, depending on the runtime implementation. In either case the GC runs normally and JVM interaction is unrestricted. The stream lifetime is not time-critical, but Dispose() should be called promptly to release the JVM resource. Write-back is handled automatically on disposal.

HPA license — forceRawMemory = true. The JVM is asked for a direct pointer to its internal array storage, avoiding any copy of the data into the managed heap. While the stream is alive the JVM garbage collector is suspended and no interaction with the JVM of any kind is permitted: no object allocation, no method calls, no blocking operations (I/O, locks, Thread.Sleep, etc.). Failing to respect these constraints may cause a deadlock or a JVM crash. Dispose() is mandatory and must be invoked immediately after the memory operation completes. Always wrap the stream in a using block.

Performance considerations. Accessing JVM-resident memory through this stream is inherently slower on a per-element basis than accessing a managed .NET array, regardless of the license or forceRawMemory setting. The JVM allocator and the CLR managed heap occupy different physical memory regions; each access risks a TLB miss or a CPU cache miss because the hardware prefetcher has no prior knowledge of the JVM pages. By contrast, a managed array obtained via ToArray() is warm in the CPU cache immediately after the copy and benefits from hardware prefetching and JIT bounds-check elimination on subsequent accesses. This stream is therefore most beneficial when the buffer is large enough that copying it would be prohibitive (hundreds of MB or more) and the access pattern is sparse or random — so that only a small fraction of elements are actually touched. For bulk sequential operations on the entire buffer, prefer JCOBridgeStream{T}.AsSpan followed by MemoryExtensions.SequenceEqual{T}(ReadOnlySpan{T}, ReadOnlySpan{T}) or a single-pass SIMD operation, which amortises the cache-miss cost over one contiguous scan.

// Standard license or HPA forceRawMemory = false — no constraints
using var stream = javaArray.ToStream<double>(FileAccess.ReadWrite);
double value = stream[0];

// HPA forceRawMemory = true — GC suspended, Dispose mandatory, no JVM calls using (var stream = javaArray.ToStream<double>(FileAccess.ReadWrite, forceRawMemory: true)) { // Only pure memory operations here — no JVM interaction of any kind. // Element-by-element access is slower than on a managed array; // use AsSpan() for bulk operations. bool eq = stream.AsSpan().SequenceEqual(otherSpan); } // GC resumes here; write-back is committed automatically