0
# Field Access and Optimization
1
2
Low-level field access optimization and reflection utilities for high-performance field operations. The field access system provides efficient mechanisms for reading and writing object fields during serialization, with optimized implementations for different runtime environments.
3
4
## Capabilities
5
6
### Field Abstract Class
7
8
Core abstraction representing a field within a schema, containing metadata and access methods for serialization operations.
9
10
```java { .api }
11
/**
12
* Abstract base class representing a field in a schema
13
*/
14
public abstract class Field<T> {
15
16
/**
17
* The protobuf wire format field type
18
*/
19
public final WireFormat.FieldType type;
20
21
/**
22
* The field number used in the wire format
23
*/
24
public final int number;
25
26
/**
27
* The field name from the Java class
28
*/
29
public final String name;
30
31
/**
32
* Whether this field represents a repeated/collection value
33
*/
34
public final boolean repeated;
35
36
/**
37
* Group filter for conditional field processing
38
*/
39
public final int groupFilter;
40
41
/**
42
* Constructor for field with tag information
43
* @param type The wire format field type
44
* @param number The field number
45
* @param name The field name
46
* @param repeated Whether field is repeated
47
* @param tag Tag annotation information
48
*/
49
protected Field(WireFormat.FieldType type, int number, String name, boolean repeated, Tag tag);
50
51
/**
52
* Constructor for non-repeated field with tag information
53
* @param type The wire format field type
54
* @param number The field number
55
* @param name The field name
56
* @param tag Tag annotation information
57
*/
58
protected Field(WireFormat.FieldType type, int number, String name, Tag tag);
59
60
/**
61
* Write field value to output stream
62
* @param output Output stream to write to
63
* @param message Object containing the field value
64
* @throws IOException if writing fails
65
*/
66
protected abstract void writeTo(Output output, T message) throws IOException;
67
68
/**
69
* Read field value from input stream and merge into message
70
* @param input Input stream to read from
71
* @param message Object to merge field value into
72
* @throws IOException if reading fails
73
*/
74
protected abstract void mergeFrom(Input input, T message) throws IOException;
75
76
/**
77
* Transfer field value through a pipe
78
* @param pipe Pipe for transfer operations
79
* @param input Input stream
80
* @param output Output stream
81
* @param repeated Whether this is a repeated field
82
* @throws IOException if transfer fails
83
*/
84
protected abstract void transfer(Pipe pipe, Input input, Output output, boolean repeated) throws IOException;
85
}
86
```
87
88
### Accessor Abstract Class
89
90
Optimized field value access abstraction providing efficient get/set operations for object fields.
91
92
```java { .api }
93
/**
94
* Abstract base class for optimized field value access
95
*/
96
public abstract class Accessor {
97
98
/**
99
* The Java reflection field this accessor operates on
100
*/
101
public final java.lang.reflect.Field f;
102
103
/**
104
* Constructor
105
* @param f Java reflection field
106
*/
107
protected Accessor(java.lang.reflect.Field f);
108
109
/**
110
* Set field value on an object
111
* @param owner Object to set field on
112
* @param value Value to set
113
*/
114
public abstract void set(Object owner, Object value);
115
116
/**
117
* Get field value from an object
118
* @param owner Object to get field from
119
* @return Field value
120
*/
121
public abstract <T> T get(Object owner);
122
123
/**
124
* Factory interface for creating accessor instances
125
*/
126
public interface Factory {
127
/**
128
* Create accessor for the specified field
129
* @param f Java reflection field
130
* @return Accessor instance
131
*/
132
Accessor create(java.lang.reflect.Field f);
133
}
134
}
135
```
136
137
### Reflection-Based Accessor
138
139
Standard accessor implementation using Java reflection for field access.
140
141
```java { .api }
142
/**
143
* Accessor implementation using Java reflection
144
*/
145
public final class ReflectAccessor extends Accessor {
146
147
/**
148
* Constructor
149
* @param f Java reflection field
150
*/
151
public ReflectAccessor(java.lang.reflect.Field f);
152
153
/**
154
* Set field value using reflection
155
* @param owner Object to set field on
156
* @param value Value to set
157
*/
158
public void set(Object owner, Object value);
159
160
/**
161
* Get field value using reflection
162
* @param owner Object to get field from
163
* @return Field value
164
*/
165
public <T> T get(Object owner);
166
167
/**
168
* Factory for creating reflection-based accessors
169
*/
170
public static final Accessor.Factory FACTORY;
171
}
172
```
173
174
### Unsafe-Based Accessor
175
176
High-performance accessor implementation using sun.misc.Unsafe for direct memory access.
177
178
```java { .api }
179
/**
180
* High-performance accessor implementation using sun.misc.Unsafe
181
* Available when USE_SUN_MISC_UNSAFE is enabled
182
*/
183
public final class UnsafeAccessor extends Accessor {
184
185
/**
186
* Constructor
187
* @param f Java reflection field
188
*/
189
public UnsafeAccessor(java.lang.reflect.Field f);
190
191
/**
192
* Set field value using unsafe direct memory access
193
* @param owner Object to set field on
194
* @param value Value to set
195
*/
196
public void set(Object owner, Object value);
197
198
/**
199
* Get field value using unsafe direct memory access
200
* @param owner Object to get field from
201
* @return Field value
202
*/
203
public <T> T get(Object owner);
204
205
/**
206
* Factory for creating unsafe-based accessors
207
*/
208
public static final Accessor.Factory FACTORY;
209
}
210
```
211
212
## Field Factory Classes
213
214
### RuntimeFieldFactory Abstract Class
215
216
Base class for field factories that create field instances based on Java reflection information.
217
218
```java { .api }
219
/**
220
* Abstract base class for runtime field factories
221
* Extends Delegate to provide custom serialization logic
222
*/
223
public abstract class RuntimeFieldFactory<V> extends Delegate<V> {
224
225
/**
226
* The Java reflection field this factory operates on
227
*/
228
public final java.lang.reflect.Field f;
229
230
/**
231
* The field number assigned to this field
232
*/
233
public final int number;
234
235
/**
236
* The field name
237
*/
238
public final String name;
239
240
/**
241
* Tag information for this field
242
*/
243
public final Tag tag;
244
245
/**
246
* Constructor
247
* @param number Field number
248
* @param name Field name
249
* @param f Java reflection field
250
* @param messageFactory Message factory for creation
251
* @param tag Tag annotation information
252
*/
253
protected RuntimeFieldFactory(int number, String name, java.lang.reflect.Field f,
254
MessageFactory messageFactory, Tag tag);
255
}
256
```
257
258
### Concrete Field Factory Implementations
259
260
Concrete implementations for different runtime environments and optimization levels.
261
262
```java { .api }
263
/**
264
* Reflection-based field factory implementation
265
*/
266
public final class RuntimeReflectionFieldFactory<V> extends RuntimeFieldFactory<V> {
267
// Implementation uses standard Java reflection
268
}
269
270
/**
271
* Unsafe-based field factory implementation
272
* Available when USE_SUN_MISC_UNSAFE is enabled
273
*/
274
public final class RuntimeUnsafeFieldFactory<V> extends RuntimeFieldFactory<V> {
275
// Implementation uses sun.misc.Unsafe for performance
276
}
277
```
278
279
## Usage Examples
280
281
### Basic Field Access
282
283
```java
284
import io.protostuff.runtime.RuntimeSchema;
285
import io.protostuff.runtime.Field;
286
287
// Get schema and access fields
288
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
289
290
// Access field by number
291
Field<User> nameField = schema.getFieldByNumber(1);
292
Field<User> ageField = schema.getFieldByNumber(2);
293
294
// Access field by name
295
Field<User> emailField = schema.getFieldByName("email");
296
297
// Get field metadata
298
System.out.println("Field name: " + nameField.name);
299
System.out.println("Field number: " + nameField.number);
300
System.out.println("Field type: " + nameField.type);
301
System.out.println("Is repeated: " + nameField.repeated);
302
```
303
304
### Custom Accessor Usage
305
306
```java
307
import io.protostuff.runtime.Accessor;
308
import io.protostuff.runtime.ReflectAccessor;
309
310
// Create accessor for a field
311
java.lang.reflect.Field javaField = User.class.getDeclaredField("name");
312
Accessor accessor = new ReflectAccessor(javaField);
313
314
// Use accessor for field operations
315
User user = new User();
316
accessor.set(user, "Alice"); // Set field value
317
String name = accessor.get(user); // Get field value
318
319
// Factory-based accessor creation
320
Accessor.Factory factory = ReflectAccessor.FACTORY;
321
Accessor factoryAccessor = factory.create(javaField);
322
```
323
324
### Performance-Optimized Field Access
325
326
```java
327
import io.protostuff.runtime.RuntimeEnv;
328
import io.protostuff.runtime.UnsafeAccessor;
329
330
// Check if unsafe is available
331
if (RuntimeEnv.USE_SUN_MISC_UNSAFE) {
332
// Use high-performance unsafe accessor
333
Accessor unsafeAccessor = new UnsafeAccessor(javaField);
334
335
// Perform high-speed field operations
336
unsafeAccessor.set(user, "FastValue");
337
String value = unsafeAccessor.get(user);
338
} else {
339
// Fall back to reflection accessor
340
Accessor reflectAccessor = new ReflectAccessor(javaField);
341
reflectAccessor.set(user, "SafeValue");
342
}
343
```
344
345
### Field Enumeration and Processing
346
347
```java
348
import java.util.List;
349
350
// Get all fields from schema
351
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
352
List<Field<User>> allFields = schema.getFields();
353
354
// Process each field
355
for (Field<User> field : allFields) {
356
System.out.printf("Field: %s (number=%d, type=%s, repeated=%s)%n",
357
field.name, field.number, field.type, field.repeated);
358
359
// Access field properties
360
if (field.groupFilter != 0) {
361
System.out.println(" Has group filter: " + field.groupFilter);
362
}
363
}
364
365
// Get field count
366
int fieldCount = schema.getFieldCount();
367
System.out.println("Total fields: " + fieldCount);
368
```
369
370
### Custom Field Processing
371
372
```java
373
// Create custom field processor
374
public class FieldAnalyzer {
375
376
public void analyzeSchema(RuntimeSchema<?> schema) {
377
for (Field<?> field : schema.getFields()) {
378
analyzeField(field);
379
}
380
}
381
382
private void analyzeField(Field<?> field) {
383
System.out.println("Analyzing field: " + field.name);
384
385
// Check field characteristics
386
if (field.repeated) {
387
System.out.println(" - Collection/repeated field");
388
}
389
390
if (field.groupFilter != 0) {
391
System.out.println(" - Has group filter: " + field.groupFilter);
392
}
393
394
// Check wire format type
395
switch (field.type) {
396
case STRING:
397
System.out.println(" - String field");
398
break;
399
case INT32:
400
System.out.println(" - Integer field");
401
break;
402
case MESSAGE:
403
System.out.println(" - Complex object field");
404
break;
405
default:
406
System.out.println(" - Other type: " + field.type);
407
}
408
}
409
}
410
```
411
412
## Performance Considerations
413
414
1. **Accessor Selection**: Use `UnsafeAccessor` when available for best performance
415
2. **Field Caching**: Cache `Field` instances to avoid repeated lookups
416
3. **Factory Pattern**: Use appropriate factory based on runtime environment
417
4. **Reflection Overhead**: Consider field access patterns in performance-critical code
418
5. **Memory Access Patterns**: Unsafe accessors provide direct memory access for minimal overhead
419
420
## Thread Safety
421
422
- **Field instances**: Immutable and thread-safe after creation
423
- **Accessor instances**: Thread-safe for field access operations
424
- **Factory instances**: Thread-safe and can be shared across threads
425
- **Field metadata**: All public fields are final and safe for concurrent access
426
427
## Error Handling
428
429
Common exceptions when working with field access:
430
431
- `IllegalAccessException` - Field access violations with reflection
432
- `SecurityException` - Security manager restrictions on field access
433
- `NoSuchFieldException` - Field not found during reflection
434
- `IllegalArgumentException` - Invalid field values or null parameters