Class BeanReader<T>

java.lang.Object
org.klojang.invoke.BeanReader<T>
Type Parameters:
T - The type of the bean

public final class BeanReader<T> extends Object
A dynamic bean reader class. This class uses method handles instead of reflection to read bean properties. However, it still uses reflection to figure out what those properties are in the first place. Therefore, if you use a BeanReader to read beans residing in a Java 9+ module, that module must be "open" to reflective access. Reflection is used only transiently. No reflection objects are cached. They are disposed of once the required information has been extracted from them.

If you prefer, you can use the BeanReaderBuilder class to configure BeanReader instances in a completely reflection-free manner. You obtain a BeanReaderBuilder via BeanReader.forClass().

Author:
Ayco Holleman
  • Constructor Details

    • BeanReader

      public BeanReader(Class<T> beanClass, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class (may be a record type)
      properties - the properties to be included/excluded
      See Also:
    • BeanReader

      public BeanReader(Class<T> beanClass, IncludeExclude includeExclude, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties to be included is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class (may be a record type)
      includeExclude - whether to include or exclude the specified properties
      properties - the properties to be included/excluded
      See Also:
    • BeanReader

      public BeanReader(Class<T> beanClass, boolean strictNaming, IncludeExclude includeExclude, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties to be included is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class (may be a record type)
      strictNaming - if false, all methods with a zero-length parameter list and a non-void return type, except getClass(), hashCode() and toString(), will be regarded as getters. Otherwise JavaBeans naming conventions will be applied regarding which methods qualify as getters. By way of exception, methods returning a Boolean are allowed to have a name starting with "is" (just like methods returning a boolean). The strictNaming parameter is tacitly ignored for record classes. Records are always processed as though strictNaming were false.
      includeExclude - whether to include or exclude the subsequently specified properties
      properties - the properties to be included/excluded
    • BeanReader

      public BeanReader(Class<T> beanClass, BeanValueTransformer<T> transformer, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class (may be a record type)
      transformer - a conversion function for bean values. The function is passed the bean from which the value was retrieved, the property that was read, and the value of the property. Using these three parameters, the function can compute a new value, which will be the value that is actually returned from BeanReader.read().
      properties - the properties to be included
    • BeanReader

      public BeanReader(Class<T> beanClass, BeanValueTransformer<T> transformer, IncludeExclude includeExclude, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties to be included is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class (may be a record type)
      transformer - a conversion function for bean values. The function is passed the bean from which the value was retrieved, the property that was read, and the value of the property. Using these three parameters, the function can compute a new value, which will be the value that is actually returned from BeanReader.read().
      includeExclude - whether to include or exclude the subsequently specified properties
      properties - the properties to be included
    • BeanReader

      public BeanReader(Class<T> beanClass, boolean strictNaming, BeanValueTransformer<T> transformer, IncludeExclude includeExclude, String... properties)
      Creates a BeanReader for the specified class. You can optionally specify an array of properties that you intend to read. If you specify a zero-length array, all properties will be readable. If you intend to use this BeanReader to repetitively read just one or two properties from bulky bean types, explicitly specifying the properties you intend to read might make the BeanReader slightly more efficient. It is not an error to specify non-existent properties. They will be tacitly ignored. A side effect of specifying one or more properties to be included is that it forces the values returned from readAllProperties() to be in the order in which you specify the properties.
      Parameters:
      beanClass - the bean class
      strictNaming - if false, all methods with a zero-length parameter list and a non-void return type, except getClass(), hashCode() and toString(), will be regarded as getters. Otherwise JavaBeans naming conventions will be applied regarding which methods qualify as getters. By way of exception, methods returning a Boolean are allowed to have a name starting with "is" (just like methods returning a boolean). The strictNaming parameter is tacitly ignored for record classes. Records are always processed as though strictNaming were false.
      transformer - a conversion function for bean values. The function is passed the bean from which the value was retrieved, the property that was read, and the value of the property. Using these three parameters, the function can compute a new value, which will be the value that is actually returned from BeanReader.read().
      includeExclude - whether to include or exclude the subsequently specified properties
      properties - the properties to be included/excluded
  • Method Details

    • forClass

      public static <T> BeanReaderBuilder<T> forClass(Class<T> beanClass)
      Returns a Builder for BeanReader instances. The builder will produce a 100% reflection-free BeanReader, which you may find desirable when writing Java 9+ modules.
      Type Parameters:
      T - the type of the objects to be read
      Parameters:
      beanClass - the class for which to create a BeanReader (may be a record type)
      Returns:
      a Builder for BeanReader instances
    • read

      public <U> U read(T bean, String property) throws NoSuchPropertyException
      Returns the value of the specified property on the specified bean. If the property does not exist a NoSuchPropertyException is thrown. If this BeanReader was instantiated with a BeanValueTransformer, the output from the transformer is returned.
      Type Parameters:
      U - the type of the return value
      Parameters:
      bean - the bean instance
      property - The property
      Returns:
      its value
      Throws:
      NoSuchPropertyException - if the specified property does not exist
    • readAllProperties

      public List<Object> readAllProperties(T bean)
      Returns the values of all readable properties in the specified JavaBean. The values will be returned in the same order as the property names returned by getReadableProperties().
      Parameters:
      bean - the bean from which to read the values
      Returns:
      the values of all readable properties in the specified JavaBean
    • getBeanClass

      public Class<T> getBeanClass()
      Returns the class of the objects this BeanReader can read.
      Returns:
      the class of the objects BeanReader can read
    • canRead

      public boolean canRead(String property)
      Returns true if the specified string represents a property that can be read by this BeanReader. Note that this check is already done by the read method before it will actually attempt to read from the provided bean. Only perform this check if there is a considerable chance that the provided string is not a readable property.
      Parameters:
      property - The string to be tested
      Returns:
      true if the specified string represents a property that can be read by this BeanReader
      See Also:
    • getReadableProperties

      public Set<String> getReadableProperties()
      Returns the properties that this BeanReader can read. If one or more properties were excluded through the constructor, they will not be contained in the returned Set. If no properties were excluded, or they were excluded via IncludeExclude.EXCLUDE, the properties will be returned in arbitrary order. If you specified one or more properties to be included (via IncludeExclude.INCLUDE), the properties will be returned in the order in which you specified those properties.
      Returns:
      the properties that this BeanReader will read
    • getIncludedGetters

      public Map<String,Getter> getIncludedGetters()
      Returns the getters used by the BeanReader to read bean properties. The returned Map maps the name of a property to the Getter used to read it.
      Returns:
      all getters used to read bean properties.