@@ -93,8 +93,8 @@ static DataType of(TypeReference<?> ref) {
9393 * handle generics. Note, in particular, that it returns {@code false}
9494 * for boxing and unboxing conversions, as does {@link Class#isAssignableFrom}.
9595 * <p>
96- * Note that this is neither weaker nor stronger than {@link #isBindableFrom}.
97- * Type variables will only accept themselves or other type variables
96+ * Note that this is neither weaker nor stronger than {@link #isBindableFrom}:
97+ * type variables will only accept themselves or other type variables
9898 * that are nominally subtypes of them,
9999 * but concrete types can be assigned from subtypes.
100100 */
@@ -103,12 +103,29 @@ default boolean isAssignableFrom(DataType other) {
103103 }
104104
105105 /**
106- * {@code A.isBindableFrom(B)} if a value of type List<B>
107- * can be passed to a method expecting List<A>.
106+ * {@code A.isBindableFrom(B)} if there exists a set of <em>bindings</em>
107+ * that would make {@code A} equal to {@code B}.
108+ * Type variables are bound by their name, so two type variables
109+ * with the same name must be bound to the same type;
110+ * wildcards can be bound to any type that conforms to their bounds.
108111 * <p>
109- * Note that this is neither weaker nor stronger than {@link #isAssignableFrom(DataType)}.
110- * Type variables will accept types that conform to their bounds,
111- * but concrete types cannot be assigned from subtypes.
112+ * This "bindable" concept does not correspond to any operation
113+ * in the Java language, but it is powerful and useful for describing
114+ * sets of related types.
115+ * For example, a type {@code List<Set<?>>} is considered bindable from
116+ * {@code List<Set<String>>}, but Java does not consider them
117+ * to match because {@code List<Set<?>>} describes a list of individually homogeneous sets
118+ * that might differ from each other,
119+ * so {@code list.add(Set.of(1,2,3))} would be allowed
120+ * even though this is not a set of {@code String}s.
121+ * Similarly, {@code List<Set<T>>} where {@code T extends CharSequence}
122+ * is bindable from {@code List<Set<String>>},
123+ * but Java does not consider them to match simply because {@code T}
124+ * represents some specific subtype of {@code CharSequence} that might not be {@code String}.
125+ * <p>
126+ * Note that this is neither weaker nor stronger than {@link #isAssignableFrom(DataType)}:
127+ * type variables will accept types that conform to their bounds,
128+ * but concrete types are invariant and don't match subtypes.
112129 */
113130 default boolean isBindableFrom (DataType other ) {
114131 return isBindableFrom (other , IS_BINDABLE , new HashMap <>());
@@ -121,12 +138,12 @@ default boolean isBindableFrom(DataType other) {
121138 * @param freeVariables if false, unbound type variables match only themselves
122139 */
123140 record BindableOptions (boolean allowSubtypes , boolean freeVariables ){
124- public static final BindableOptions IS_BINDABLE = new BindableOptions (false , true );
125- public static final BindableOptions IS_ASSIGNABLE = new BindableOptions (true , false );
141+ static final BindableOptions IS_ASSIGNABLE = new BindableOptions (true , false );
142+ static final BindableOptions IS_BINDABLE = new BindableOptions (false , true );
126143
127144 /**
128145 * Often, whether subtypes are allowed varies during the matching process.
129- * This lets us assert a new value for that flag while keeping the other the same .
146+ * This lets us assert a new value for that flag while keeping the rest unchanged .
130147 */
131148 public BindableOptions withAllowSubtypes (boolean v ) {
132149 return new BindableOptions (v , this .freeVariables );
0 commit comments