【问题标题】:Invoking class constructor by explicitly specifying type witness通过显式指定类型见证来调用类构造函数
【发布时间】:2017-03-11 09:19:47
【问题描述】:

Oracle docs on Java generics type inference 给出了这个例子:

class MyClass<X> {
  <T> MyClass(T t) {
    // ...
  }
}

考虑以下 MyClass 类的实例化:

new MyClass&lt;Integer&gt;("")

该语句为正式类型参数X 显式指定类型Integer。编译器为形式类型参数T 推断类型String,因为此构造函数的实际参数是一个String 对象。

我尝试过这个。我定义了以下类:

class Box<T,S> 
{
    T item;
    S otherItem;

    <X> Box(S p1, X p2)
    {
        otherItem = p1;
    }

    public static void main(String[] args) 
    {
        /* Below gives compile time error:
           The constructor Box<String,Integer>(String, int) is undefined
        */
        Box box4 = new Box<String,Integer>("Mahesh",11);
    }
}

以上对构造函数的调用给了我编译时错误:

The constructor Box<String,Integer>(String, int) is undefined

我知道我可以通过指定菱形来做到这一点:

Box box4 = new Box<>("Mahesh",11);

但只是好奇,我该如何通过明确指定type witness来做到这一点...

【问题讨论】:

    标签: java generics


    【解决方案1】:

    回答你的问题:

    我怎样才能通过明确指定类型见证来做到这一点...

    您在new 和类名之间加上尖括号:

    new <TypeWitnessForConstructor> Box<TypeArgumentsForInstance>(...)
    

    但这不是您的代码的问题,正如 Sweeper 的回答所示。

    【讨论】:

      【解决方案2】:

      这就是您的代码不起作用的原因。

      Box&lt;String,Integer&gt; 是指Box 类型,泛型类型参数T 等于StringS 等于Integer。对吧?

      通过替换已知的泛型参数,Box&lt;String, Integer&gt; 的构造函数签名为:

      <X> Box(Integer p1, X p2)
      

      这是你调用构造函数的方式:

      new Box<String,Integer>("Mahesh",11)
      

      您将String 作为第一个参数,但构造函数需要Integer。编译器错误!

      您有很多方法可以解决这个问题。要么交换两个泛型类型参数的位置,要么在调用构造函数时交换参数的位置。

      【讨论】:

      • 同样在调用构造函数&lt;X&gt; Box(X a)的情况下,指定的类型见证将是class Box&lt;T,S&gt;的类型,但不对应于构造函数签名&lt;X&gt; Box(X a)中的X。但是,如果我有方法private static &lt;K&gt; void printK(K a){},我必须调用Box.&lt;Integer&gt;printK(2),即在方法签名中指定与K 对应的类型见证。对吗?
      • @Mahesha999 不,您将类型参数放在方法名称之后。我在外面,所以我无法测试把它放在前面是否有效。
      • 我猜你理解错了。我指的是在调用构造函数的情况下,为类类型(class Box&lt;T,S&gt;)指定类型见证(不是构造函数类型X Box(X a){}),但在方法调用的情况下,为方法类型指定类型见证(@ 987654341@).
      • @Mahesha999 是的,每个类型参数都是可选的,如果不指定,默认为Object
      猜你喜欢
      • 1970-01-01
      • 2017-05-11
      • 2017-01-28
      • 1970-01-01
      • 2021-05-24
      • 2021-11-26
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多