GraalVM Polyglot API for multi-language runtime environments with host-guest interoperability and security controls.
—
The Value class is the central abstraction for language-agnostic operations on polyglot values. It provides seamless interoperability between host (Java) and guest languages, enabling type conversion, container operations, and function execution across language boundaries.
The Value class provides comprehensive type checking and conversion capabilities for all supported polyglot value types.
public final class Value extends AbstractValue {
// Null and basic type checks
public boolean isNull();
public boolean isNumber();
public boolean isBoolean();
public boolean isString();
// Object type checks
public boolean isHostObject();
public boolean isProxyObject();
public boolean isNativePointer();
// Temporal type checks
public boolean isDate();
public boolean isTime();
public boolean isTimeZone();
public boolean isDuration();
public boolean isInstant();
// Exception checking
public boolean isException();
}Type Checking Example:
Context context = Context.create("js");
Value stringValue = context.eval("js", "'Hello World'");
Value numberValue = context.eval("js", "42.5");
Value arrayValue = context.eval("js", "[1, 2, 3]");
Value objectValue = context.eval("js", "({name: 'Alice', age: 30})");
System.out.println(stringValue.isString()); // true
System.out.println(numberValue.isNumber()); // true
System.out.println(arrayValue.hasArrayElements()); // true
System.out.println(objectValue.hasMembers()); // true// Primitive type conversion
public boolean asBoolean();
public String asString();
public int asInt();
public long asLong();
public float asFloat();
public double asDouble();
public byte asByte();
public short asShort();
// Temporal type conversion
public LocalDate asDate();
public LocalTime asTime();
public ZoneId asTimeZone();
public Duration asDuration();
public Instant asInstant();
// Object type conversion
public long asNativePointer();
public <T> T asHostObject();
public <T extends Proxy> T asProxyObject();Type Conversion Examples:
Context context = Context.create("js");
// JavaScript number to Java types
Value jsNumber = context.eval("js", "Math.PI");
double pi = jsNumber.asDouble(); // 3.141592653589793
int piInt = jsNumber.asInt(); // 3 (truncated)
String piStr = jsNumber.asString(); // "3.141592653589793"
// JavaScript string to Java types
Value jsString = context.eval("js", "'42'");
int fromString = jsString.asInt(); // 42 (parsed)
String original = jsString.asString(); // "42"
// JavaScript boolean
Value jsBool = context.eval("js", "true");
boolean bool = jsBool.asBoolean(); // true
String boolStr = jsBool.asString(); // "true"// Type-safe conversion with Class
public <T> T as(Class<T> targetType);
// Type-safe conversion with TypeLiteral
public <T> T as(TypeLiteral<T> targetType);Generic Conversion Examples:
Context context = Context.create("js");
// JavaScript array to Java List
Value jsArray = context.eval("js", "[1, 2, 3, 4, 5]");
List<Integer> javaList = jsArray.as(List.class);
System.out.println(javaList); // [1, 2, 3, 4, 5]
// JavaScript object to Java Map
Value jsObject = context.eval("js", "({name: 'Alice', age: 30})");
Map<String, Object> javaMap = jsObject.as(Map.class);
System.out.println(javaMap.get("name")); // "Alice"
// Custom type conversion with TypeLiteral
Value jsListOfMaps = context.eval("js", "[{x: 1}, {x: 2}, {x: 3}]");
TypeLiteral<List<Map<String, Integer>>> listType = new TypeLiteral<List<Map<String, Integer>>>() {};
List<Map<String, Integer>> typedList = jsListOfMaps.as(listType);The Value class provides unified access to container-like objects including arrays, objects with members, and hash maps.
// Array type checking and access
public boolean hasArrayElements();
public long getArraySize();
public Value getArrayElement(long index);
public void setArrayElement(long index, Object value);
public boolean removeArrayElement(long index);Array Manipulation Examples:
Context context = Context.create("js");
// Create and access JavaScript array
Value jsArray = context.eval("js", "['hello', 'world', 42, true]");
System.out.println(jsArray.hasArrayElements()); // true
System.out.println(jsArray.getArraySize()); // 4
// Access elements
System.out.println(jsArray.getArrayElement(0).asString()); // "hello"
System.out.println(jsArray.getArrayElement(2).asInt()); // 42
// Modify array
jsArray.setArrayElement(1, "polyglot");
jsArray.setArrayElement(4, "new element"); // Extends array
// Remove elements
jsArray.removeArrayElement(3); // Remove boolean true
System.out.println(jsArray.getArraySize()); // 4// Object member operations
public boolean hasMembers();
public Set<String> getMemberKeys();
public boolean hasMember(String identifier);
public Value getMember(String identifier);
public void putMember(String identifier, Object value);
public boolean removeMember(String identifier);Member Access Examples:
Context context = Context.create("js");
// Create JavaScript object
Value jsObject = context.eval("js", """
({
name: 'Alice',
age: 30,
greet: function() { return 'Hello, ' + this.name; },
address: {
city: 'San Francisco',
country: 'USA'
}
})
""");
System.out.println(jsObject.hasMembers()); // true
// Get all member keys
Set<String> keys = jsObject.getMemberKeys();
System.out.println(keys); // [name, age, greet, address]
// Access members
System.out.println(jsObject.getMember("name").asString()); // "Alice"
System.out.println(jsObject.getMember("age").asInt()); // 30
// Access nested members
Value address = jsObject.getMember("address");
System.out.println(address.getMember("city").asString()); // "San Francisco"
// Modify members
jsObject.putMember("age", 31);
jsObject.putMember("email", "alice@example.com");
// Remove members
jsObject.removeMember("address");
System.out.println(jsObject.hasMember("address")); // false// Hash map operations (for languages that support map-like objects)
public boolean hasHashEntries();
public long getHashSize();
public boolean hasHashEntry(Object key);
public Value getHashValue(Object key);
public Value getHashValueOrDefault(Object key, Object defaultValue);
public void putHashEntry(Object key, Object value);
public boolean removeHashEntry(Object key);
public Value getHashEntriesIterator();
public Value getHashKeysIterator();
public Value getHashValuesIterator();Hash Operations Examples:
Context context = Context.create("js");
// Create a Map-like structure
Value jsMap = context.eval("js", "new Map([['key1', 'value1'], ['key2', 42]])");
if (jsMap.hasHashEntries()) {
System.out.println(jsMap.getHashSize()); // 2
// Access values
System.out.println(jsMap.getHashValue("key1").asString()); // "value1"
System.out.println(jsMap.getHashValue("key2").asInt()); // 42
// Add/modify entries
jsMap.putHashEntry("key3", "new value");
jsMap.putHashEntry("key1", "updated value");
// Iterate over entries
Value entriesIterator = jsMap.getHashEntriesIterator();
while (entriesIterator.hasIteratorNextElement()) {
Value entry = entriesIterator.getIteratorNextElement();
Value key = entry.getArrayElement(0);
Value value = entry.getArrayElement(1);
System.out.printf("%s -> %s%n", key.asString(), value.toString());
}
}// Iterator support
public boolean hasIterator();
public Value getIterator();
public boolean isIterator();
public boolean hasIteratorNextElement();
public Value getIteratorNextElement();Iterator Examples:
Context context = Context.create("js");
// JavaScript iterable
Value jsIterable = context.eval("js", "[10, 20, 30, 40, 50]");
if (jsIterable.hasIterator()) {
Value iterator = jsIterable.getIterator();
while (iterator.hasIteratorNextElement()) {
Value element = iterator.getIteratorNextElement();
System.out.println(element.asInt());
}
}
// Custom iterator from JavaScript generator
Value jsGenerator = context.eval("js", """
(function* fibonacci() {
let a = 0, b = 1;
while (a < 100) {
yield a;
[a, b] = [b, a + b];
}
})()
""");
while (jsGenerator.hasIteratorNextElement()) {
Value fib = jsGenerator.getIteratorNextElement();
System.out.println(fib.asInt()); // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
}The Value class supports executing functions and constructors from guest languages with type-safe parameter passing.
// Function execution
public boolean canExecute();
public Value execute(Object... arguments);
public void executeVoid(Object... arguments);
// Constructor invocation
public boolean canInstantiate();
public Value newInstance(Object... arguments);
// Member method invocation
public boolean canInvokeMember(String identifier);
public Value invokeMember(String identifier, Object... arguments);Function Execution Examples:
Context context = Context.create("js");
// Define JavaScript function
Value jsFunction = context.eval("js", """
function calculate(operation, a, b) {
switch(operation) {
case 'add': return a + b;
case 'multiply': return a * b;
case 'power': return Math.pow(a, b);
default: return null;
}
}
calculate;
""");
if (jsFunction.canExecute()) {
Value result1 = jsFunction.execute("add", 5, 3);
Value result2 = jsFunction.execute("multiply", 4, 7);
Value result3 = jsFunction.execute("power", 2, 8);
System.out.println(result1.asInt()); // 8
System.out.println(result2.asInt()); // 28
System.out.println(result3.asInt()); // 256
}
// Constructor invocation
Value jsClass = context.eval("js", """
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name} and I'm ${this.age} years old.`;
}
}
Person;
""");
if (jsClass.canInstantiate()) {
Value person = jsClass.newInstance("Alice", 30);
Value greeting = person.invokeMember("greet");
System.out.println(greeting.asString()); // "Hello, I'm Alice and I'm 30 years old."
}Context context = Context.create("js");
// JavaScript object with methods
Value jsObject = context.eval("js", """
({
data: [1, 2, 3, 4, 5],
sum: function() {
return this.data.reduce((a, b) => a + b, 0);
},
filter: function(predicate) {
return this.data.filter(predicate);
},
map: function(transform) {
return this.data.map(transform);
}
})
""");
// Invoke methods
Value sum = jsObject.invokeMember("sum");
System.out.println(sum.asInt()); // 15
// Pass function as argument
Value squares = jsObject.invokeMember("map", context.eval("js", "x => x * x"));
System.out.println(squares.as(List.class)); // [1, 4, 9, 16, 25]
// Chain method calls
Value evenNumbers = jsObject.invokeMember("filter", context.eval("js", "x => x % 2 === 0"));
System.out.println(evenNumbers.as(List.class)); // [2, 4]For languages that support binary data, the Value class provides low-level buffer operations.
// Buffer operations
public boolean hasBufferElements();
public boolean isBufferWritable();
public long getBufferSize();
// Byte operations
public byte readBufferByte(long byteOffset);
public void writeBufferByte(long byteOffset, byte value);
// Multi-byte operations with endianness
public short readBufferShort(ByteOrder order, long byteOffset);
public void writeBufferShort(ByteOrder order, long byteOffset, short value);
public int readBufferInt(ByteOrder order, long byteOffset);
public void writeBufferInt(ByteOrder order, long byteOffset, int value);
public long readBufferLong(ByteOrder order, long byteOffset);
public void writeBufferLong(ByteOrder order, long byteOffset, long value);
public float readBufferFloat(ByteOrder order, long byteOffset);
public void writeBufferFloat(ByteOrder order, long byteOffset, float value);
public double readBufferDouble(ByteOrder order, long byteOffset);
public void writeBufferDouble(ByteOrder order, long byteOffset, double value);Buffer Operations Example:
Context context = Context.create("js");
// Create JavaScript ArrayBuffer
Value jsBuffer = context.eval("js", "new ArrayBuffer(32)");
if (jsBuffer.hasBufferElements()) {
System.out.println("Buffer size: " + jsBuffer.getBufferSize()); // 32
System.out.println("Writable: " + jsBuffer.isBufferWritable()); // true
// Write various data types
jsBuffer.writeBufferInt(ByteOrder.BIG_ENDIAN, 0, 0x12345678);
jsBuffer.writeBufferFloat(ByteOrder.LITTLE_ENDIAN, 4, 3.14159f);
jsBuffer.writeBufferDouble(ByteOrder.BIG_ENDIAN, 8, Math.E);
// Read back the data
int intValue = jsBuffer.readBufferInt(ByteOrder.BIG_ENDIAN, 0);
float floatValue = jsBuffer.readBufferFloat(ByteOrder.LITTLE_ENDIAN, 4);
double doubleValue = jsBuffer.readBufferDouble(ByteOrder.BIG_ENDIAN, 8);
System.out.printf("Int: 0x%08X%n", intValue); // 0x12345678
System.out.printf("Float: %f%n", floatValue); // 3.141590
System.out.printf("Double: %f%n", doubleValue); // 2.718282
}The Value class provides access to meta-information about objects and their types.
// Meta-object operations
public Value getMetaObject();
public boolean isMetaObject();
public String getMetaQualifiedName();
public String getMetaSimpleName();
public boolean isMetaInstance(Object instance);
public boolean hasMetaParents();
public Value getMetaParents();Meta-Object Examples:
Context context = Context.create("js");
// Create JavaScript object and get its meta-object
Value jsObject = context.eval("js", "new Date()");
Value metaObject = jsObject.getMetaObject();
if (metaObject.isMetaObject()) {
System.out.println("Type name: " + metaObject.getMetaSimpleName()); // "Date"
System.out.println("Qualified name: " + metaObject.getMetaQualifiedName()); // "Date"
// Check if another object is instance of this type
Value anotherDate = context.eval("js", "new Date(2023, 0, 1)");
boolean isInstance = metaObject.isMetaInstance(anotherDate);
System.out.println("Is instance: " + isInstance); // true
// Check parents/prototypes
if (metaObject.hasMetaParents()) {
Value parents = metaObject.getMetaParents();
System.out.println("Has parent types: " + parents.getArraySize());
}
}Context context = Context.newBuilder("js")
.allowHostAccess(HostAccess.EXPLICIT)
.build();
// Java class with exported members
public class Calculator {
@HostAccess.Export
public double add(double a, double b) {
return a + b;
}
@HostAccess.Export
public double multiply(double a, double b) {
return a * b;
}
}
// Convert to Value and use in JavaScript
Value calculatorValue = context.asValue(new Calculator());
Value jsBindings = context.getBindings("js");
jsBindings.putMember("calc", calculatorValue);
Value result = context.eval("js", "calc.add(calc.multiply(3, 4), 5)");
System.out.println(result.asDouble()); // 17.0Context context = Context.create("js");
// Create JavaScript object with rich behavior
Value jsLibrary = context.eval("js", """
({
version: '1.0.0',
users: new Map(),
addUser: function(id, name, email) {
this.users.set(id, {name: name, email: email, created: new Date()});
return this.users.get(id);
},
getUser: function(id) {
return this.users.get(id);
},
getAllUsers: function() {
return Array.from(this.users.values());
}
})
""");
// Use JavaScript object in Java
Value newUser = jsLibrary.invokeMember("addUser", 1, "Alice", "alice@example.com");
System.out.println("Created user: " + newUser.getMember("name").asString());
Value user = jsLibrary.invokeMember("getUser", 1);
System.out.println("Retrieved user: " + user.getMember("email").asString());
Value allUsers = jsLibrary.invokeMember("getAllUsers");
System.out.println("Total users: " + allUsers.getArraySize());// Exception handling
public boolean isException();
public RuntimeException throwException();Exception Handling Example:
Context context = Context.create("js");
try {
Value jsError = context.eval("js", """
(function() {
throw new Error('Something went wrong in JavaScript');
})()
""");
if (jsError.isException()) {
jsError.throwException(); // Throws PolyglotException
}
} catch (PolyglotException e) {
System.out.println("Caught polyglot exception: " + e.getMessage());
if (e.isGuestException()) {
Value guestError = e.getGuestObject();
System.out.println("Guest error message: " + guestError.getMember("message").asString());
}
}// Utility methods
public Context getContext();
public SourceSection getSourceLocation();
public void pin();
public static Value asValue(Object o);Utility Examples:
Context context = Context.create("js");
Value jsValue = context.eval("js", "Math.PI");
// Get associated context
Context valueContext = jsValue.getContext();
System.out.println("Same context: " + (context == valueContext)); // true
// Pin value to prevent garbage collection
jsValue.pin();
// Static conversion method
Value staticValue = Value.asValue("Hello from static method");Context context = Context.create("js");
// Cache frequently accessed values
Value jsArrayPrototype = context.eval("js", "Array.prototype");
Value pushMethod = jsArrayPrototype.getMember("push");
// Reuse cached values
Value myArray = context.eval("js", "[]");
pushMethod.execute(myArray, 1, 2, 3); // Efficient method callContext context = Context.create("js");
Value jsArray = context.eval("js", "[]");
// Batch array modifications
for (int i = 0; i < 1000; i++) {
jsArray.setArrayElement(i, i * i);
}
// More efficient: use JavaScript for bulk operations
context.getBindings("js").putMember("data", IntStream.range(0, 1000).toArray());
Value processedArray = context.eval("js", "data.map(x => x * x)");Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-polyglot--graalvm-sdk