在 java 中,new 关键字后面的 NonWildcardTypeArguments 的用途是什么?

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

我在翻阅 java language spec 时看到了这种写创作者的方式:

Creator:  
NonWildcardTypeArguments CreatedName ClassCreatorRest

明码:

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

在我能想到的每个示例中,据我所知,class 列表没有用。能否请您举例说明新关键字后的类型列表何时起作用。

除非您运行进入类型可变构造函数的极其奇特java语法构造函数,否则此功能无效。从本质上讲,您永远不应该这样做。它是为了语言的完整性,可能永远不应该添加到 java.

你可以把类型参数定义放在类上,这是最常见的模式。例如,ArrayList 有一个类型变量;声明如下:

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

第一个 <E> 声明有某种类型 E 没有边界。然后立即使用它(第一个 <E> 和第二个 <E> 看起来相同,但一个声明类型 var,另一个是类型 var 用法,因此这些是完全不同的。到目前为止一切顺利.

但您也可以直接在方法上声明它们。例如:

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

此方法可以使用任意数量的对象引用来调用,并且将 return 第一个不是 null 的对象引用,并且调用的类型将是所有对象引用的共同点参数。换句话说,这将编译:

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

而如果我们写了它:

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

然后,虽然 coalesce(null, someStringRef, "default") 显然必然会 return 一个 String,但编译器不知道这一点,因此 String x = coalesce(..) 不会编译。你必须注入演员表。泛型的重点是不必这样做。

现在回答你的问题

同样的功能(方法类型参数)在构造函数上可用:

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

合法java。很难想象您想要在构造函数上使用泛型的情况。构造函数没有 return 类型,重点是构造函数只需要类型参数,并且一旦你完成它就停止所有相关性(如果它与实例本身相关,你会把它在类型上,就像上面示例中的 <E> 一样)。因此,为什么您从未在 java 代码中有效地看到它。然而,如果你要写它, 你不希望 javac 推断泛型,而是想明确说明它,你正在阅读的语法是你会怎么做:

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

将调用该构造函数并强制 AStringTInteger.

JLS 中有大量奇怪且令人困惑的结构,但从未有人使用过。因此,通读 JLS 通常不是一个好主意,您会学到一些东西,但这是一种非常低效的学习方式。