通过显式指定类型见证来调用类构造函数

时间:2017-03-07 07:40:42

标签: java generics

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

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

考虑以下MyClass类的实例化:

     

new MyClass<Integer>("")

     

该语句显式指定了正式类型参数Integer的类型X。编译器为形式类型参数String推断类型T,因为此构造函数的实际参数是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 来实现这一目标......

2 个答案:

答案 0 :(得分:2)

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

Box<String,Integer>表示Box类型,其泛型类型参数T等于StringS等于Integer 。正确?

通过替换已知的通用参数,Box<String, Integer>的构造函数签名是:

<X> Box(Integer p1, X p2)

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

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

你给它一个String作为第一个参数,但构造函数需要一个Integer。编译错误!

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

答案 1 :(得分:2)

回答你的问题:

  

如何通过明确指定类型见证...

来完成此操作

您在new和班级名称之间放置了尖括号:

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

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