Why in this case does the Streams API need a hint of a generic type?

Failed to compile the following:

    @NotNull String defaultFormatter(@Nullable Object value) {
        if (value instanceof Collection) {
            return ((Collection) value).stream()
                        .map(MyClass::defaultFormatter)
                        .collect(Collectors.joining(eol));
        }
        return String.valueOf(value);
    }

In particular, when compiling with javac, the error will be:

Error:(809, 94) java: incompatible types: 
      java.lang.Object cannot be converted to 
      @org.jetbrains.annotations.NotNull java.lang.String

But the following compiles simply:

    @NotNull String defaultFormatter(@Nullable Object value) {
        if (value instanceof Collection) {
            Stream<String> stream = ((Collection) value).stream()
                         .map(MyClass::defaultFormatter);
            return stream.collect(Collectors.joining(eol));
        }
        return String.valueOf(value);
    }

The only difference is that I introduced an additional variable. Note that I did not quit, so the semantic changes have not changed.

Can anyone explain why this is necessary?

+4
source share
1 answer

This top of this answer mostly says Radiodef in the comments above. I do not want to steal these words, but the answer below ---does not really work without a preliminary explanation.

Radiodef, , , , Collection. Collection<?>, :

        return ((Collection<?>) value).stream()
                    .map(MyClass::defaultFormatter)
                    .collect(Collectors.joining(eol));

, , . , :

        Stream<String> stream = ((Collection) value).stream()
                     .map(MyClass::defaultFormatter);

RHS Stream; Stream<String>, JLS Sec 5.1.9:

(§4.8) G G<T1,...,Tn>.


, , . : , , .

, Stream.collect, Stream raw, , :

  • Stream.collect(Collector<? super T,A,R> collector) R;
  • R Object

collect Object, . List<String> , List.

+4

Source: https://habr.com/ru/post/1679886/


All Articles