Java注释 – Printed.toSysOut().withLabel(“source-stream”)

huangapple go评论64阅读模式
英文:

Java Notation - Printed.<String, String>toSysOut().withLabel("source-stream")

问题

我很熟悉Java,但是一段时间以前用过它。我遇到了一些新的东西,比如

Printed.<String, String>toSysOut().withLabel("source-stream")

特别是,突出显示的部分,似乎<String, String>是toSysOut()的返回类型。大多数情况下,我看到的是

Printed.toSysOut().withLabel("source-stream")

这是什么符号表示法,其中返回类型与引用运算符(.)一起使用?

英文:

I knew Java well, however, used it some time back . I come across something new such as

> Printed.<String, String>toSysOut().withLabel("source-stream")

Esp , highlighted part , it seems <String, String> is return type of toSysOut() . Most of the time , i see such as

> Printed.toSysOut().withLabel("source-stream")

What kind of notation is that, where the return type is used along with the reference operator (.)

答案1

得分: 6

Java有一种叫做'类型参数'的东西。它们可以使用另一种类型来参数化一个类型。例如:

List<String> iCanOnlyContainStrings = new ArrayList<String>();
iCanOnlyContainStrings.add(5); // 不会编译!

方法也可以被参数化。例如:

public <T> T firstNonNull(T... inputs) {
    for (T input : inputs) if (input != null) return input;
}

这个方法说明了存在一种我们将其称为T的类型。我们对它一无所知,但是这个方法的参数类型和返回类型都是相同的类型。因此,你可以这样调用它:

String a = firstNonNull("b", "c");

这是合法的。如果你写成了:

public Object firstNonNull(Object... inputs) {
    for (Object input : inputs) if (input != null) return input;
}

那么你需要强制转换firstNonNull方法的返回值:(String) firstNonNull(...)

通常情况下,Java会推断出你想要的类型。但如果你想明确指定,你可以这样做,这就是你在这里看到的语法:

public class Example {
    public static <T> T firstNonNull(T... inputs) {
        for (T input : inputs) if (input != null) return input;
    }

    public static void invokeExample() {
        Serializable s = Example.<Serializable>firstNonNull(null, null);
    }
}

你必须使用.来明确指定,有时这意味着你必须编写this.foo()YourType.foo(),只是为了有一个点。

另一种编写你上面的代码的方式是这样的:

Printer<String, String> printer = Printed.toSysOut();

现在Java的推断会正确推断出方法'toSysOut'上的类型变量应该是StringString。这种语法在这些链式构建器类型场景中最常见,因为Java不会无休止地向前查找以进行推断。例如,这个不起作用:

List<String> names = ImmutableList.builder().add("Hello").add("World").build();

因为builder()方法是有参数的,Java不会查看所有的add方法,只是为了知道你可能想要什么(也不会向前查找到build()方法,然后回到变量声明)。因此,你会经常看到这种情况:

List<String> names = ImmutableList.<String>builder().add(...).build();
英文:

Java has something called 'type parameters'. They can, well, parameterize a type using another type. For example:

List&lt;String&gt; iCanOnlyContainStrings = new ArrayList&lt;String&gt;();
iCanOnlyContainStrings.add(5); // does not compile!

Methods can also be parameterized. For example:

public &lt;T&gt; T firstNonNull(T... inputs) {
    for (T input : inputs) if (input != null) return input;
}

This method states that there is some type which we shall call T. We know nothing about it, but this method's argument types AND its return type are all the same type. Thus, you can invoke it as follows:

String a = firstNonNull(&quot;b&quot;, &quot;c&quot;);

and this just compiles. Had you written:

public Object firstNonNull(Object... inputs) {
    for (Object input : inputs) if (input != null) return input;
}

Then you would need to cast the return value of the firstNonNull method: (String) firstNonNull(...).

Normally java will infer the type you wanted here. But if you want to be explicit about it, you can do that, and that is the syntax you see here:

public class Example {
    public static &lt;T&gt; T firstNonNull(T... inputs) {
        for (T input : inputs) if (input != null) return input;
    }

    public static void invokeExample() {
        Serializable s = Example.&lt;Serializable&gt;firstNonNull(null, null);
    }
}

You must have the '.' to be explicit, which sometimes means you have to resort to writing this.foo() or YourType.foo() just so you have a dot.

Another way to write the code you have up there is something like:

Printer&lt;String, String&gt; printer = Printed.toSysOut();

Now java's inference will correctly infer the type vars on the method 'toSysOut' are intended to be String and String. This syntax is most commonly observed in these chained builder type scenarios, because java won't look ahead endlessly to infer. FOr example, this does not work:

List&lt;String&gt; names = ImmutableList.builder().add(&quot;Hello&quot;).add(&quot;World&quot;).build();

because the builder() method is parameterized, and java is not going to inspect all your add methods just to know what you probably wanted (nor look ahead to the build() method, then warp back to the variable declaration). Thus, you see this a ton:

List&lt;String&gt; names = ImmutableList.&lt;String&gt;builder().add(...).build();

huangapple
  • 本文由 发表于 2020年7月21日 21:40:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/63015814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定