0
# Value Operations
1
2
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.
3
4
## Capabilities
5
6
### Type Checking
7
8
Check the type and capabilities of polyglot values.
9
10
```java { .api }
11
public final class Value extends AbstractValue {
12
// Basic type checks
13
public boolean isString();
14
public boolean isNumber();
15
public boolean isBoolean();
16
public boolean isNull();
17
public boolean isDate();
18
public boolean isTime();
19
public boolean isTimeZone();
20
public boolean isDuration();
21
public boolean isInstant();
22
23
// Object capability checks
24
public boolean hasMembers();
25
public boolean hasArrayElements();
26
public boolean hasBufferElements();
27
public boolean hasIterator();
28
public boolean isIterator();
29
public boolean hasHashEntries();
30
31
// Execution capability checks
32
public boolean canExecute();
33
public boolean canInstantiate();
34
35
// Host object checks
36
public boolean isHostObject();
37
public boolean isProxyObject();
38
public boolean isNativePointer();
39
40
// Meta object checks
41
public boolean isMetaObject();
42
public boolean isMetaInstance(Value metaObject);
43
}
44
```
45
46
**Usage:**
47
48
```java
49
try (Context context = Context.create("js")) {
50
Value jsObject = context.eval("js", "({name: 'Alice', age: 30, greet: function() { return 'Hello'; }})");
51
52
System.out.println("Has members: " + jsObject.hasMembers()); // true
53
System.out.println("Can execute: " + jsObject.canExecute()); // false
54
55
Value greetFunction = jsObject.getMember("greet");
56
System.out.println("Can execute: " + greetFunction.canExecute()); // true
57
58
Value jsArray = context.eval("js", "[1, 2, 3]");
59
System.out.println("Has array elements: " + jsArray.hasArrayElements()); // true
60
System.out.println("Array size: " + jsArray.getArraySize()); // 3
61
}
62
```
63
64
### Value Conversion
65
66
Convert polyglot values to Java types.
67
68
```java { .api }
69
public String asString();
70
public boolean asBoolean();
71
public byte asByte();
72
public short asShort();
73
public int asInt();
74
public long asLong();
75
public float asFloat();
76
public double asDouble();
77
public LocalDate asDate();
78
public LocalTime asTime();
79
public ZoneId asTimeZone();
80
public Duration asDuration();
81
public Instant asInstant();
82
public long asNativePointer();
83
public <T> T asHostObject();
84
public <T> T as(Class<T> targetType);
85
public <T> T as(TypeLiteral<T> targetType);
86
```
87
88
**Usage:**
89
90
```java
91
try (Context context = Context.create("js")) {
92
// Number conversions
93
Value jsNumber = context.eval("js", "42.7");
94
int intVal = jsNumber.asInt(); // 42 (truncated)
95
double doubleVal = jsNumber.asDouble(); // 42.7
96
97
// String conversion
98
Value jsString = context.eval("js", "'Hello World'");
99
String strVal = jsString.asString(); // "Hello World"
100
101
// Boolean conversion
102
Value jsBool = context.eval("js", "true");
103
boolean boolVal = jsBool.asBoolean(); // true
104
105
// Host object conversion
106
MyJavaClass javaObj = new MyJavaClass();
107
context.getBindings("js").putMember("javaObj", javaObj);
108
Value val = context.getBindings("js").getMember("javaObj");
109
MyJavaClass retrieved = val.asHostObject(); // Original Java object
110
111
// Generic type conversion
112
List<String> list = val.as(new TypeLiteral<List<String>>() {});
113
}
114
```
115
116
### Member Operations
117
118
Access and manipulate object members.
119
120
```java { .api }
121
public boolean hasMember(String key);
122
public Value getMember(String key);
123
public void putMember(String key, Object value);
124
public boolean removeMember(String key);
125
public Set<String> getMemberKeys();
126
```
127
128
**Usage:**
129
130
```java
131
try (Context context = Context.create("js")) {
132
Value jsObject = context.eval("js", "({})");
133
134
// Add members
135
jsObject.putMember("name", "Alice");
136
jsObject.putMember("age", 30);
137
jsObject.putMember("greet", context.eval("js", "function() { return 'Hello ' + this.name; }"));
138
139
// Check member existence
140
System.out.println("Has name: " + jsObject.hasMember("name")); // true
141
142
// Get members
143
Value name = jsObject.getMember("name");
144
System.out.println("Name: " + name.asString()); // "Alice"
145
146
// Get all member keys
147
Set<String> keys = jsObject.getMemberKeys();
148
System.out.println("Keys: " + keys); // [name, age, greet]
149
150
// Remove member
151
boolean removed = jsObject.removeMember("age");
152
System.out.println("Removed age: " + removed); // true
153
}
154
```
155
156
### Array Operations
157
158
Access and manipulate array elements.
159
160
```java { .api }
161
public boolean hasArrayElements();
162
public Value getArrayElement(long index);
163
public void setArrayElement(long index, Object value);
164
public boolean removeArrayElement(long index);
165
public long getArraySize();
166
```
167
168
**Usage:**
169
170
```java
171
try (Context context = Context.create("js")) {
172
Value jsArray = context.eval("js", "[10, 20, 30]");
173
174
// Check array properties
175
System.out.println("Has array elements: " + jsArray.hasArrayElements()); // true
176
System.out.println("Array size: " + jsArray.getArraySize()); // 3
177
178
// Access elements
179
Value firstElement = jsArray.getArrayElement(0);
180
System.out.println("First element: " + firstElement.asInt()); // 10
181
182
// Modify elements
183
jsArray.setArrayElement(1, 99);
184
System.out.println("Modified element: " + jsArray.getArrayElement(1).asInt()); // 99
185
186
// Remove elements (if supported by language)
187
boolean removed = jsArray.removeArrayElement(2);
188
System.out.println("Removed element: " + removed);
189
}
190
```
191
192
### Buffer Operations
193
194
Access and manipulate buffer elements for binary data.
195
196
```java { .api }
197
public boolean hasBufferElements();
198
public long getBufferSize();
199
public byte readBufferByte(long byteOffset);
200
public short readBufferShort(ByteOrder order, long byteOffset);
201
public int readBufferInt(ByteOrder order, long byteOffset);
202
public long readBufferLong(ByteOrder order, long byteOffset);
203
public float readBufferFloat(ByteOrder order, long byteOffset);
204
public double readBufferDouble(ByteOrder order, long byteOffset);
205
public void writeBufferByte(long byteOffset, byte value);
206
public void writeBufferShort(ByteOrder order, long byteOffset, short value);
207
public void writeBufferInt(ByteOrder order, long byteOffset, int value);
208
public void writeBufferLong(ByteOrder order, long byteOffset, long value);
209
public void writeBufferFloat(ByteOrder order, long byteOffset, float value);
210
public void writeBufferDouble(ByteOrder order, long byteOffset, double value);
211
public boolean isBufferWritable();
212
```
213
214
**Usage:**
215
216
```java
217
try (Context context = Context.create("js")) {
218
// Create a buffer in JavaScript
219
Value buffer = context.eval("js", "new ArrayBuffer(16)");
220
Value view = context.eval("js", "new Int32Array(buffer)");
221
222
if (view.hasBufferElements()) {
223
System.out.println("Buffer size: " + view.getBufferSize()); // 16
224
225
// Write to buffer
226
view.writeBufferInt(ByteOrder.LITTLE_ENDIAN, 0, 1234);
227
view.writeBufferInt(ByteOrder.LITTLE_ENDIAN, 4, 5678);
228
229
// Read from buffer
230
int val1 = view.readBufferInt(ByteOrder.LITTLE_ENDIAN, 0); // 1234
231
int val2 = view.readBufferInt(ByteOrder.LITTLE_ENDIAN, 4); // 5678
232
233
System.out.println("Values: " + val1 + ", " + val2);
234
}
235
}
236
```
237
238
### Function Execution
239
240
Execute callable values and instantiate constructors.
241
242
```java { .api }
243
public boolean canExecute();
244
public Value execute(Object... arguments);
245
public Value executeVoid(Object... arguments);
246
public boolean canInstantiate();
247
public Value newInstance(Object... arguments);
248
```
249
250
**Usage:**
251
252
```java
253
try (Context context = Context.create("js")) {
254
// Execute function
255
Value mathMax = context.eval("js", "Math.max");
256
if (mathMax.canExecute()) {
257
Value result = mathMax.execute(10, 20, 5);
258
System.out.println("Max: " + result.asInt()); // 20
259
}
260
261
// Execute method with void return
262
Value consoleLog = context.eval("js", "console.log");
263
consoleLog.executeVoid("Hello from Java!");
264
265
// Instantiate constructor
266
Value DateConstructor = context.eval("js", "Date");
267
if (DateConstructor.canInstantiate()) {
268
Value dateInstance = DateConstructor.newInstance(2023, 11, 25);
269
System.out.println("Date: " + dateInstance.toString());
270
}
271
272
// Execute with mixed arguments
273
Value customFunction = context.eval("js",
274
"(function(name, age, active) { return {name, age, active}; })");
275
Value person = customFunction.execute("Alice", 30, true);
276
System.out.println("Name: " + person.getMember("name").asString());
277
}
278
```
279
280
### Iterator Operations
281
282
Work with iterable and iterator values.
283
284
```java { .api }
285
public boolean hasIterator();
286
public Value getIterator();
287
public boolean isIterator();
288
public boolean hasIteratorNextElement();
289
public Value getIteratorNextElement();
290
```
291
292
**Usage:**
293
294
```java
295
try (Context context = Context.create("js")) {
296
Value jsArray = context.eval("js", "[1, 2, 3]");
297
298
if (jsArray.hasIterator()) {
299
Value iterator = jsArray.getIterator();
300
301
while (iterator.hasIteratorNextElement()) {
302
Value element = iterator.getIteratorNextElement();
303
System.out.println("Element: " + element.asInt());
304
}
305
}
306
307
// Work with Map iterator
308
Value jsMap = context.eval("js", "new Map([['a', 1], ['b', 2]])");
309
Value mapIterator = jsMap.getMember("entries").execute();
310
311
while (mapIterator.hasIteratorNextElement()) {
312
Value entry = mapIterator.getIteratorNextElement();
313
Value key = entry.getArrayElement(0);
314
Value value = entry.getArrayElement(1);
315
System.out.println(key.asString() + " -> " + value.asInt());
316
}
317
}
318
```
319
320
### Hash Map Operations
321
322
Work with hash map-like structures.
323
324
```java { .api }
325
public boolean hasHashEntries();
326
public long getHashSize();
327
public boolean hasHashEntry(Value key);
328
public Value getHashValue(Value key);
329
public void putHashEntry(Value key, Value value);
330
public boolean removeHashEntry(Value key);
331
public Value getHashEntriesIterator();
332
public Value getHashKeysIterator();
333
public Value getHashValuesIterator();
334
```
335
336
**Usage:**
337
338
```java
339
try (Context context = Context.create("js")) {
340
Value jsMap = context.eval("js", "new Map()");
341
342
if (jsMap.hasHashEntries()) {
343
// Add entries
344
jsMap.putHashEntry(context.asValue("key1"), context.asValue("value1"));
345
jsMap.putHashEntry(context.asValue("key2"), context.asValue("value2"));
346
347
System.out.println("Map size: " + jsMap.getHashSize()); // 2
348
349
// Check and get entries
350
Value key1 = context.asValue("key1");
351
if (jsMap.hasHashEntry(key1)) {
352
Value value = jsMap.getHashValue(key1);
353
System.out.println("Value: " + value.asString()); // "value1"
354
}
355
356
// Iterate entries
357
Value entriesIterator = jsMap.getHashEntriesIterator();
358
while (entriesIterator.hasIteratorNextElement()) {
359
Value entry = entriesIterator.getIteratorNextElement();
360
System.out.println("Entry: " + entry);
361
}
362
}
363
}
364
```
365
366
### Meta Object Operations
367
368
Work with language meta objects and type information.
369
370
```java { .api }
371
public Value getMetaObject();
372
public boolean isMetaObject();
373
public String getMetaQualifiedName();
374
public String getMetaSimpleName();
375
public boolean isMetaInstance(Value metaObject);
376
```
377
378
**Usage:**
379
380
```java
381
try (Context context = Context.create("js")) {
382
Value jsArray = context.eval("js", "[1, 2, 3]");
383
384
// Get meta object (constructor/prototype)
385
Value metaObject = jsArray.getMetaObject();
386
if (metaObject.isMetaObject()) {
387
System.out.println("Type: " + metaObject.getMetaQualifiedName()); // "Array"
388
System.out.println("Simple name: " + metaObject.getMetaSimpleName()); // "Array"
389
}
390
391
// Check instance relationship
392
Value ArrayConstructor = context.eval("js", "Array");
393
boolean isArrayInstance = jsArray.isMetaInstance(ArrayConstructor);
394
System.out.println("Is Array instance: " + isArrayInstance); // true
395
396
// Work with custom types
397
Value customObject = context.eval("js", "class Person { constructor(name) { this.name = name; } }; new Person('Alice')");
398
Value personMeta = customObject.getMetaObject();
399
System.out.println("Custom type: " + personMeta.getMetaQualifiedName()); // "Person"
400
}
401
```
402
403
## Value Equality and Comparison
404
405
Values support equality checking and toString conversion:
406
407
```java
408
Value val1 = context.eval("js", "42");
409
Value val2 = context.eval("js", "42");
410
411
// Values are equal if they represent the same value
412
System.out.println("Equal: " + val1.equals(val2)); // Implementation dependent
413
414
// Convert to string representation
415
System.out.println("String: " + val1.toString()); // "42"
416
```
417
418
## Performance Considerations
419
420
- **Type Checking**: Perform type checks before conversions to avoid exceptions
421
- **Member Caching**: Cache frequently accessed members to avoid repeated lookups
422
- **Conversion Costs**: Some conversions may be expensive; cache converted values when possible
423
- **Array Access**: Direct array element access is typically faster than iterator-based access