Interface VirtualField<T>
- Type Parameters:
T
- the value type of the variable
- All Known Implementing Classes:
VirtualField.ReadOnly
Comparison with Reflected Fields
Virtual fields differ from objects of class Field
in several ways:
- Need not refer to an actual field.
- No runtime metadata.
- Access is not dynamically bound.
- The owner is bound at construction time.
- Can optionally be read-only.
Getting and Setting
Getting the value of a virtual field is effected using the method get()
(inherited from Supplier
).
Virtual fields have serveral operations that deal with setting:
accept(T)
- is a method that takes the new value, and returns
nothing (inherited from
Consumer
). swap(T)
- is a method that takes the new value, and returns the old
value (analogous to
Map.put(K, V)
). modify(T)
- is a method that takes the new value, and indicates
change (analogous to
Set.add(E)
). swapWith
,modifyWith
- are
methods that take a function to compute the new value from the old one
(analogous to
Stream.map(java.util.function.Function<? super T, ? extends R>)
). computeIfAbsent(java.util.function.Supplier<? extends T>)
,computeIfPresent(java.util.function.Function<? super T, ? extends T>)
,merge(T,java.util.function.BiFunction<? super T,? super T,? extends T>)
- make a virtual field behave like a single-place, keyless
Map
.
Setter Default Implementations
The setter variants can each be implemented in terms of one of the others.
The default implementations take swap(T)
as primitive and abstract.
If, for some custom implementation, it is more natural to define one of
modify(T)
or accept(T)
as primitive, then swap(T)
can be
defined in terms of that one, and get()
.
Aliasing
Having two distinct virtual fields does not guarantee that the underlying storage does not coincide. In fact, one may be some proxy or view of the other.
Thread Safety
Virtual fields are not inherently thread-safe.
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic class
Base class for virtual fields that cannot be set. -
Method Summary
Modifier and TypeMethodDescriptiondefault void
Sets a new value for this virtual field and forgets the old one (optional operation).default VirtualField.ReadOnly
<T> Creates a virtual field that is a read-only proxy of this field.default T
computeIfAbsent
(Supplier<? extends T> supp) Sets a new value for this virtual field if the old value is null, and returns the new value.default T
computeIfPresent
(Function<? super T, ? extends T> fun) Sets a new value for this virtual field based on the old value if it is non-null, and returns the new value.static <T> VirtualField.ReadOnly
<T> constant
(T value) Creates a virtual field that always has the given value.static <T> VirtualField
<T> Creates a virtual field backed by a list element.static <K,
T> VirtualField <T> Creates a virtual field backed by a map element.static <T> VirtualField
<T> elementAt
(T[] array, int index) Creates a virtual field backed by an array element.get()
Returns the current value of this virtual field.default VirtualField
<T> Returns a virtual field backed by this field that admits only certain new values.default boolean
Checks whether this virtual field is read-only.default T
Sets a new value for this virtual field based on the old value if it is non-null, and a given value, and returns the new value.default boolean
Sets a new value for this virtual field and indicates change (optional operation).default boolean
modifyWith
(Function<? super T, ? extends T> fun) Sets a new value for this virtual field based on the old value, and indicates change.static <T> VirtualField.ReadOnly
<T> Creates a virtual field that can be read using the given getter operation.static <T> VirtualField
<T> Creates a virtual field with a new backing field that can be read and written.static <T> VirtualField
<T> Creates a virtual field that can be read and written using the given getter and setter operations, respectively.static <T> VirtualField
<T> readWrite
(T initialValue) Creates a virtual field with a new backing field that can be read and written.Sets a new value for this virtual field and returns the old value (optional operation).default T
Sets a new value for this virtual field based on the old value, and returns the old value.
-
Method Details
-
get
T get()Returns the current value of this virtual field. -
isReadOnly
default boolean isReadOnly()Checks whether this virtual field is read-only.The default implementation always returns
false
; subclasses may override to realize read-only virtual fields.- Returns:
false
if the value can be set;true
if the value cannot be set
-
asReadOnly
Creates a virtual field that is a read-only proxy of this field.- Returns:
- a read-only virtual field from which the value can be gotten as from this field
-
swap
Sets a new value for this virtual field and returns the old value (optional operation).- Returns:
- the old value of this virtual field
- Throws:
UnsupportedOperationException
- if this virtual field cannot be set
-
modify
Sets a new value for this virtual field and indicates change (optional operation).- Returns:
true
if the value has changed- Throws:
UnsupportedOperationException
- if this virtual field cannot be set
-
accept
Sets a new value for this virtual field and forgets the old one (optional operation).This method adds no functionality over
swap(T)
andmodify(T)
, but just implementsSupplier
.- Specified by:
accept
in interfaceConsumer<T>
- Throws:
UnsupportedOperationException
- if this virtual field cannot be set
-
swapWith
Sets a new value for this virtual field based on the old value, and returns the old value.- Parameters:
fun
- a function for computing the new value given the old one- Returns:
- the old value of this virtual field
- Throws:
NullPointerException
- iffun
is nullUnsupportedOperationException
- if this virtual field cannot be set
-
modifyWith
Sets a new value for this virtual field based on the old value, and indicates change.- Parameters:
fun
- a function for computing the new value given the old one- Returns:
true
if the value has changed- Throws:
NullPointerException
- iffun
is nullUnsupportedOperationException
- if this attribute cannot be set
-
computeIfAbsent
Sets a new value for this virtual field if the old value is null, and returns the new value.- Parameters:
supp
- used to compute the new value if the old value is null- Returns:
- the old value of this virtual field if non-null, or otherwise the new value
- Throws:
NullPointerException
- ifsupp
is nullUnsupportedOperationException
- if this virtual field cannot be set- See Also:
-
computeIfPresent
Sets a new value for this virtual field based on the old value if it is non-null, and returns the new value.- Parameters:
fun
- a function for computing the new value given the old, non-null one- Returns:
- the old value of this virtual field if null, or otherwise the new value
- Throws:
NullPointerException
- iffun
is nullUnsupportedOperationException
- if this attribute cannot be set- See Also:
-
merge
Sets a new value for this virtual field based on the old value if it is non-null, and a given value, and returns the new value. If the old value is null, it is simply replaced by the given one.- Parameters:
value
- the given valuefun
- a function for computing the new value from the old, non-null value, and the given value- Returns:
- the new value of this field; either the combination of the old and the given value or just the given one
- Throws:
NullPointerException
- iffun
is nullUnsupportedOperationException
- if this attribute cannot be set- See Also:
-
constant
Creates a virtual field that always has the given value.- Type Parameters:
T
- the value type of the variable- Parameters:
value
- the given value- Returns:
- a virtual field that always has that
value
-
readOnly
Creates a virtual field that can be read using the given getter operation.The created virtual field is read-only.
- Type Parameters:
T
- the value type of the variable- Parameters:
getter
- an operation that reads the variable value- Returns:
- a virtual field that can be read using
getter
- Throws:
NullPointerException
- ifgetter
is null
-
readWrite
Creates a virtual field with a new backing field that can be read and written.The field value is initialized to
null
.This is useful for giving anonymous classes and lambda expression write access to local variables.
- Returns:
- a virtual field with a new backing field
-
readWrite
Creates a virtual field with a new backing field that can be read and written.This is useful for giving anonymous classes and lambda expression write access to local variables.
- Parameters:
initialValue
- the initial field value- Returns:
- a virtual field with a new backing field
-
readWrite
Creates a virtual field that can be read and written using the given getter and setter operations, respectively.- Type Parameters:
T
- the value type of the variable- Parameters:
getter
- an operation that reads the variable valuesetter
- an operation that writes the variable value- Returns:
- a virtual field that can be read using
getter
, and written usingsetter
- Throws:
NullPointerException
- ifgetter
orsetter
is null
-
elementAt
Creates a virtual field backed by an array element.The length of an array is fixed. Hence a check that
index
is a valid index inarray
is performed eagerly at construction time.- Type Parameters:
T
- the value type of the variable- Parameters:
array
- the backing arrayindex
- the selected index- Returns:
- a virtual field backed by the element
array[index]
- Throws:
NullPointerException
- ifarray
is nullArrayIndexOutOfBoundsException
- ifindex
is out of bounds inarray
-
elementAt
Creates a virtual field backed by a list element.The length of a list is variable. Hence checks that
index
is a valid index inlist
is performed lazily at use time.- Type Parameters:
T
- the value type of the variable- Parameters:
list
- the backing listindex
- the selected index- Returns:
- a virtual field backed by the element at
index
inlist
- Throws:
NullPointerException
- iflist
is null
-
elementAt
Creates a virtual field backed by a map element.All keys of the correct type are valid in a map; the use of the
null
key is discouraged, because not all maps support it.- Type Parameters:
K
- the key type of the backing mapT
- the value type of the variable- Parameters:
map
- the backing mapkey
- the selected key- Returns:
- a virtual field backed by the element at
key
inlist
- Throws:
NullPointerException
- ifmap
is null
-
guard
Returns a virtual field backed by this field that admits only certain new values.For read-only virtual fields, there is no inadmissible setting to prevent, and hence the backing field itself is returned. For writable virtual fields, a proxy is created.
The proxy does not prevent inadmissible results from arising by other means, such as being present since before its construction, or being set directly on the backing field, circumventing the proxy.
- Parameters:
admissible
- a check whether some value is admissible- Returns:
this
for read-only fields; otherwise a virtual field from which the value of this virtual field can be gotten, but which can be set only to admissible values (attempting to set inadmissible values will causeIllegalArgumentException
)- Throws:
NullPointerException
- ifadmissible
is null
-