This provides an opportunity for me to promote what I believe is a much more
important missing interface, namely, an interface that supports a semantic
replacement for type casting.
Using type casting (instanceof) is a really bad way to test an object for an
optional capability.
The reason is that instanceof is strictly limited by how the object is
implemented. It will only work if the object *directly* implements the
interface. It does not support an object that might provide the requested
interface using an auxiliary object. It doesn’t support delegation at all. If
you try to wrap an object with a transparent wrapper implemented using
delegation, the wrapper must support exactly the interfaces that you expect
from the wrapped object. If some of those are optional, you wind up with many
versions of the wrapper to ensure that instanceof will work on the wrapper as
expected.
This is hardly a new idea. I’ve seen this idea in several major libraries. But,
because Java does define its own version of this interface, this approach
cannot be used in general.
I suspect it would be useful for some of the problems being discussed here.
For concreteness, this is how I define it:
public interface Extensible
{
<T> @Nullable T getExtension(@NotNull Class<T> c);
}
with a static method used in place of instanceof:
public static <T> @Nullable T getExtension(@Nullable Object o, @NotNull
Class<T> c)
{
if (o == null) {
return null;
}
if (c.isInstance(o)) {
return c.cast(o);
}
if (o instanceof Extensible) {
Extensible x = (Extensible) o;
return x.getExtension(c);
}
return null;
}
> On Aug 17, 2021, at 10:54 AM, CC007
> <[email protected]> wrote:
>
> On Mon, 9 Aug 2021 12:28:23 GMT, CC007 <[email protected]>
> wrote:
>
>> create Streamable and ParallelStreamable interface and use them in
>> Collection and Optional
>
> Ah ok, I see your point. In the case that you want to have something be only
> `Streamable`, you can create an interface like this (fixed missing method
> type param and added `ofCollection`:
>
> public interface Streamable<T> {
>
> Stream<T> stream();
>
> static <T> Streamable<T> ofIterable(Iterable<T> iterable) {
> return () -> StreamSupport.stream(iterable.spliterator(), false);
> }
>
> static <T> Streamable<T> ofCollection(Collection<T> collection) {
> return collection::stream;
> }
> }
>
> This will indeed allow you to only expose the `stream()` method, even to the
> degree that you can't even expose the other methods with type casting, which
> is a nice side effect. You could also add a static method for `ofOptional`,
> if required, but you made a good point about `Optional.stream`'s general use
> case (though it could still be used as a stream when needed).
>