GraalVM Polyglot API for embedding multiple programming languages in Java applications with secure language interoperability
—
Value operations provide universal representation and manipulation for cross-language data exchange. Values enable seamless interaction with guest language objects, arrays, functions, and primitives while maintaining type safety and providing automatic conversions.
Check the type and capabilities of polyglot values.
public final class Value extends AbstractValue {
// Basic type checks
public boolean isString();
public boolean isNumber();
public boolean isBoolean();
public boolean isNull();
public boolean isDate();
public boolean isTime();
public boolean isTimeZone();
public boolean isDuration();
public boolean isInstant();
// Object capability checks
public boolean hasMembers();
public boolean hasArrayElements();
public boolean hasBufferElements();
public boolean hasIterator();
public boolean isIterator();
public boolean hasHashEntries();
// Execution capability checks
public boolean canExecute();
public boolean canInstantiate();
// Host object checks
public boolean isHostObject();
public boolean isProxyObject();
public boolean isNativePointer();
// Meta object checks
public boolean isMetaObject();
public boolean isMetaInstance(Value metaObject);
}Usage:
try (Context context = Context.create("js")) {
Value jsObject = context.eval("js", "({name: 'Alice', age: 30, greet: function() { return 'Hello'; }})");
System.out.println("Has members: " + jsObject.hasMembers()); // true
System.out.println("Can execute: " + jsObject.canExecute()); // false
Value greetFunction = jsObject.getMember("greet");
System.out.println("Can execute: " + greetFunction.canExecute()); // true
Value jsArray = context.eval("js", "[1, 2, 3]");
System.out.println("Has array elements: " + jsArray.hasArrayElements()); // true
System.out.println("Array size: " + jsArray.getArraySize()); // 3
}Convert polyglot values to Java types.
public String asString();
public boolean asBoolean();
public byte asByte();
public short asShort();
public int asInt();
public long asLong();
public float asFloat();
public double asDouble();
public LocalDate asDate();
public LocalTime asTime();
public ZoneId asTimeZone();
public Duration asDuration();
public Instant asInstant();
public long asNativePointer();
public <T> T asHostObject();
public <T> T as(Class<T> targetType);
public <T> T as(TypeLiteral<T> targetType);Usage:
try (Context context = Context.create("js")) {
// Number conversions
Value jsNumber = context.eval("js", "42.7");
int intVal = jsNumber.asInt(); // 42 (truncated)
double doubleVal = jsNumber.asDouble(); // 42.7
// String conversion
Value jsString = context.eval("js", "'Hello World'");
String strVal = jsString.asString(); // "Hello World"
// Boolean conversion
Value jsBool = context.eval("js", "true");
boolean boolVal = jsBool.asBoolean(); // true
// Host object conversion
MyJavaClass javaObj = new MyJavaClass();
context.getBindings("js").putMember("javaObj", javaObj);
Value val = context.getBindings("js").getMember("javaObj");
MyJavaClass retrieved = val.asHostObject(); // Original Java object
// Generic type conversion
List<String> list = val.as(new TypeLiteral<List<String>>() {});
}Access and manipulate object members.
public boolean hasMember(String key);
public Value getMember(String key);
public void putMember(String key, Object value);
public boolean removeMember(String key);
public Set<String> getMemberKeys();Usage:
try (Context context = Context.create("js")) {
Value jsObject = context.eval("js", "({})");
// Add members
jsObject.putMember("name", "Alice");
jsObject.putMember("age", 30);
jsObject.putMember("greet", context.eval("js", "function() { return 'Hello ' + this.name; }"));
// Check member existence
System.out.println("Has name: " + jsObject.hasMember("name")); // true
// Get members
Value name = jsObject.getMember("name");
System.out.println("Name: " + name.asString()); // "Alice"
// Get all member keys
Set<String> keys = jsObject.getMemberKeys();
System.out.println("Keys: " + keys); // [name, age, greet]
// Remove member
boolean removed = jsObject.removeMember("age");
System.out.println("Removed age: " + removed); // true
}Access and manipulate array elements.
public boolean hasArrayElements();
public Value getArrayElement(long index);
public void setArrayElement(long index, Object value);
public boolean removeArrayElement(long index);
public long getArraySize();Usage:
try (Context context = Context.create("js")) {
Value jsArray = context.eval("js", "[10, 20, 30]");
// Check array properties
System.out.println("Has array elements: " + jsArray.hasArrayElements()); // true
System.out.println("Array size: " + jsArray.getArraySize()); // 3
// Access elements
Value firstElement = jsArray.getArrayElement(0);
System.out.println("First element: " + firstElement.asInt()); // 10
// Modify elements
jsArray.setArrayElement(1, 99);
System.out.println("Modified element: " + jsArray.getArrayElement(1).asInt()); // 99
// Remove elements (if supported by language)
boolean removed = jsArray.removeArrayElement(2);
System.out.println("Removed element: " + removed);
}Access and manipulate buffer elements for binary data.
public boolean hasBufferElements();
public long getBufferSize();
public byte readBufferByte(long byteOffset);
public short readBufferShort(ByteOrder order, long byteOffset);
public int readBufferInt(ByteOrder order, long byteOffset);
public long readBufferLong(ByteOrder order, long byteOffset);
public float readBufferFloat(ByteOrder order, long byteOffset);
public double readBufferDouble(ByteOrder order, long byteOffset);
public void writeBufferByte(long byteOffset, byte value);
public void writeBufferShort(ByteOrder order, long byteOffset, short value);
public void writeBufferInt(ByteOrder order, long byteOffset, int value);
public void writeBufferLong(ByteOrder order, long byteOffset, long value);
public void writeBufferFloat(ByteOrder order, long byteOffset, float value);
public void writeBufferDouble(ByteOrder order, long byteOffset, double value);
public boolean isBufferWritable();Usage:
try (Context context = Context.create("js")) {
// Create a buffer in JavaScript
Value buffer = context.eval("js", "new ArrayBuffer(16)");
Value view = context.eval("js", "new Int32Array(buffer)");
if (view.hasBufferElements()) {
System.out.println("Buffer size: " + view.getBufferSize()); // 16
// Write to buffer
view.writeBufferInt(ByteOrder.LITTLE_ENDIAN, 0, 1234);
view.writeBufferInt(ByteOrder.LITTLE_ENDIAN, 4, 5678);
// Read from buffer
int val1 = view.readBufferInt(ByteOrder.LITTLE_ENDIAN, 0); // 1234
int val2 = view.readBufferInt(ByteOrder.LITTLE_ENDIAN, 4); // 5678
System.out.println("Values: " + val1 + ", " + val2);
}
}Execute callable values and instantiate constructors.
public boolean canExecute();
public Value execute(Object... arguments);
public Value executeVoid(Object... arguments);
public boolean canInstantiate();
public Value newInstance(Object... arguments);Usage:
try (Context context = Context.create("js")) {
// Execute function
Value mathMax = context.eval("js", "Math.max");
if (mathMax.canExecute()) {
Value result = mathMax.execute(10, 20, 5);
System.out.println("Max: " + result.asInt()); // 20
}
// Execute method with void return
Value consoleLog = context.eval("js", "console.log");
consoleLog.executeVoid("Hello from Java!");
// Instantiate constructor
Value DateConstructor = context.eval("js", "Date");
if (DateConstructor.canInstantiate()) {
Value dateInstance = DateConstructor.newInstance(2023, 11, 25);
System.out.println("Date: " + dateInstance.toString());
}
// Execute with mixed arguments
Value customFunction = context.eval("js",
"(function(name, age, active) { return {name, age, active}; })");
Value person = customFunction.execute("Alice", 30, true);
System.out.println("Name: " + person.getMember("name").asString());
}Work with iterable and iterator values.
public boolean hasIterator();
public Value getIterator();
public boolean isIterator();
public boolean hasIteratorNextElement();
public Value getIteratorNextElement();Usage:
try (Context context = Context.create("js")) {
Value jsArray = context.eval("js", "[1, 2, 3]");
if (jsArray.hasIterator()) {
Value iterator = jsArray.getIterator();
while (iterator.hasIteratorNextElement()) {
Value element = iterator.getIteratorNextElement();
System.out.println("Element: " + element.asInt());
}
}
// Work with Map iterator
Value jsMap = context.eval("js", "new Map([['a', 1], ['b', 2]])");
Value mapIterator = jsMap.getMember("entries").execute();
while (mapIterator.hasIteratorNextElement()) {
Value entry = mapIterator.getIteratorNextElement();
Value key = entry.getArrayElement(0);
Value value = entry.getArrayElement(1);
System.out.println(key.asString() + " -> " + value.asInt());
}
}Work with hash map-like structures.
public boolean hasHashEntries();
public long getHashSize();
public boolean hasHashEntry(Value key);
public Value getHashValue(Value key);
public void putHashEntry(Value key, Value value);
public boolean removeHashEntry(Value key);
public Value getHashEntriesIterator();
public Value getHashKeysIterator();
public Value getHashValuesIterator();Usage:
try (Context context = Context.create("js")) {
Value jsMap = context.eval("js", "new Map()");
if (jsMap.hasHashEntries()) {
// Add entries
jsMap.putHashEntry(context.asValue("key1"), context.asValue("value1"));
jsMap.putHashEntry(context.asValue("key2"), context.asValue("value2"));
System.out.println("Map size: " + jsMap.getHashSize()); // 2
// Check and get entries
Value key1 = context.asValue("key1");
if (jsMap.hasHashEntry(key1)) {
Value value = jsMap.getHashValue(key1);
System.out.println("Value: " + value.asString()); // "value1"
}
// Iterate entries
Value entriesIterator = jsMap.getHashEntriesIterator();
while (entriesIterator.hasIteratorNextElement()) {
Value entry = entriesIterator.getIteratorNextElement();
System.out.println("Entry: " + entry);
}
}
}Work with language meta objects and type information.
public Value getMetaObject();
public boolean isMetaObject();
public String getMetaQualifiedName();
public String getMetaSimpleName();
public boolean isMetaInstance(Value metaObject);Usage:
try (Context context = Context.create("js")) {
Value jsArray = context.eval("js", "[1, 2, 3]");
// Get meta object (constructor/prototype)
Value metaObject = jsArray.getMetaObject();
if (metaObject.isMetaObject()) {
System.out.println("Type: " + metaObject.getMetaQualifiedName()); // "Array"
System.out.println("Simple name: " + metaObject.getMetaSimpleName()); // "Array"
}
// Check instance relationship
Value ArrayConstructor = context.eval("js", "Array");
boolean isArrayInstance = jsArray.isMetaInstance(ArrayConstructor);
System.out.println("Is Array instance: " + isArrayInstance); // true
// Work with custom types
Value customObject = context.eval("js", "class Person { constructor(name) { this.name = name; } }; new Person('Alice')");
Value personMeta = customObject.getMetaObject();
System.out.println("Custom type: " + personMeta.getMetaQualifiedName()); // "Person"
}Values support equality checking and toString conversion:
Value val1 = context.eval("js", "42");
Value val2 = context.eval("js", "42");
// Values are equal if they represent the same value
System.out.println("Equal: " + val1.equals(val2)); // Implementation dependent
// Convert to string representation
System.out.println("String: " + val1.toString()); // "42"Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-polyglot--polyglot