简体   繁体   English

在 java 中,新关键字之后的 NonWildcardTypeArguments 的目的是什么?

[英]In java what is the purpose of NonWildcardTypeArguments following the new keyword?

I was looking through the java language spec and saw this way of writing a creator:我正在查看java 语言规范,并看到了这种编写创建者的方式:

Creator:  
NonWildcardTypeArguments CreatedName ClassCreatorRest

In plain code:在纯代码中:

new <Integer> String("1");
// or
new <String,Integer> Integer(5);
//or
new <Constructor,String,Integer> ArrayList<String>(5);

In every example I can think of the class list is not useful as far as I can tell.在每个示例中,据我所知,class 列表没有用。 Can you please give me an example when the typelist after the new keyword serves a purpose.当新关键字之后的类型列表起作用时,你能给我一个例子吗?

This feature is invalid unless you run into the extremely exotic java syntactical constructor of a type-varred constructor.除非您遇到非常奇特的 java 类型变量构造函数的语法构造函数,否则此功能无效。 Essentially, you should never be doing this.本质上,您永远不应该这样做。 It's there for language completeness and probably should never have been added to java.它是为了语言的完整性,可能永远不应该添加到 java 中。

You can put type param definitions on classes, this is the most common mode.您可以将类型参数定义放在类上,这是最常见的模式。 For example, ArrayList has a type variable;例如ArrayList有一个类型变量; it is declared as follows:声明如下:

class ArrayList<E> implements List<E> { ... }

The first <E> declares that there is some type E with no bounds.第一个<E>声明有一些没有边界的类型E It is then used immediately (the first <E> and the second <E> look identical, but one declares the type var, the other is a type var usage, and thus these are quite different. So far so good.然后立即使用它(第一个<E>和第二个<E>看起来相同,但是一个声明了 var 类型,另一个是 var 类型的用法,因此它们完全不同。到目前为止一切都很好。

But you can also declare them directly on a method.但是您也可以直接在方法上声明它们。 For example:例如:

public static <E> coalesce(E... items) {
  for (E item : items) if (item != null) return item;
  return item;
}

This method can be invoked with as many object refs as you please and will return the first one that isn't null , and the invocation's type will be the common denominator amongst all the parameters.可以使用尽可能多的 object 引用来调用此方法,并将返回第一个不是null的引用,并且调用的类型将是所有参数中的公分母。 In other words, this would compile:换句话说,这将编译:

String x = coalesce(null, someString, "defaultValue");

Whereas if we had written it:而如果我们写了它:

public static Object coalesce(Object... items) {
  for (E item : items) if (item != null) return item;
  return item;
}

Then, whilst coalesce(null, someStringRef, "default") would obviously neccessarily return a String , the compiler doesn't know that and thus String x = coalesce(..) would NOT compile.然后,虽然coalesce(null, someStringRef, "default")显然必须返回一个String ,但编译器不知道这一点,因此String x = coalesce(..)不会编译。 You'd have to inject a cast.你必须注入演员表。 The point of generics is to not have to do that. generics 的重点是不必这样做。

And now to the answer to your question现在回答你的问题

This same feature (on-method type params) is available on constructors:构造函数也可以使用相同的功能(方法类型参数):

public class Example<T> {
  public <A> Example(A first, A second) {
  }
}

is legal java.是合法的 java。 It is extremely difficult to attempt to think of a situation where you'd want on-constructor generics.很难想出一个你想要构造函数 generics 的情况。 Constructors have no return type, and the whole point is that the typeparam is needed just for the constructor and ceases all relevance once you're done with it (if it is relevant to the instance itself, you'd put it on the type, just like <E> in the example above).构造函数没有返回类型,关键是 typeparam 只是构造函数需要,一旦你完成它就会停止所有相关性(如果它与实例本身相关,你会把它放在类型上,就像上面示例中的<E>一样)。 Hence why you see it effectively never in java code.因此,为什么您从未在 java 代码中有效地看到它。 Nevertheless, if you were to write it, and you don't want javac to infer the generics but instead want to be explicit about it, the syntax you are reading about is how you'd do it:不过,如果您要编写它,并且您不希望javac推断 generics 而是想明确说明它,那么您正在阅读的语法就是您将如何做到这一点:

new <String>Example<Integer>("a", "b");

Would invoke that constructor and force A to be String and E to be Integer .将调用该构造函数并强制AStringEInteger

There are boatloads of weird and confusing constructs in the JLS that nobody ever uses. JLS 中有大量奇怪且令人困惑的构造,没有人使用过。 Hence it's not generally a good idea to just read through the JLS, you'll learn something but it is a highly inefficient way of learning things.因此,通读 JLS 通常不是一个好主意,您会学到一些东西,但这是一种非常低效的学习方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM