简体   繁体   中英

Invoking class constructor by explicitly specifying type witness

Oracle docs on Java generics type inference gives this exmaple:

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

Consider the following instantiation of the class MyClass:

new MyClass<Integer>("")

The statement explicitly specifies the type Integer for the formal type parameter, X . The compiler infers the type String for the formal type parameter, T , because the actual parameter of this constructor is a String object.

I tried to experiment with this. I defined following class:

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);
    }
}

Above call to constructor gives me compile time error:

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

I know I can do this by specifying the diamond:

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

But just curious, how can I do this by explicitly specifying type witness ...

Here's why your code does not work.

By Box<String,Integer> you mean a Box type with the generic type parameter T being equal to String and S being equal to Integer . Right?

By replacing known generic arguments, the constructor's signature for Box<String, Integer> is:

<X> Box(Integer p1, X p2)

This is how you call the constructor:

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

You gave it a String as the first argument, but the constructor expects an Integer . Compiler Error!

You have lots of ways to work around this. Either swap the positions of the two generic type arguments, or swap the positions of the arguments when calling the constructor.

To answer your question:

how can I do this by explicitly specifying type witness...

You put in angle brackets between the new and the class name:

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

But that is not the problem with your code, as Sweeper's answer shows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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