简体   繁体   中英

Extended generic type

I've got the following code:

public class GenericsTest<T extends Number> {

    public void doSomething(T v1, T v2) {
    }

    public void test()
    {
        GenericsTest<T> test = new GenericsTest<>();
        //test.doSomething(new Integer(0), new Integer(1)); Not ok
    }
}

In test() I create GenericsTest<T> where T extends Number , but I can not pass any number.

The method doSomething(T, T) in the type GenericsTest is not applicable for the arguments (Integer, Integer)

Why I can not pass an Integer if T is Number as well as Integer ?

you need to define the generic instance with a valid type

public static void main(String[] args) {
    final GenericsTest<Integer> test = new GenericsTest<>();
    test.doSomething(new Integer(0), new Integer(1)); // now is ok
}

then you need to add constraint to the method doSomething

 public <T extends Number> void doSomething(T v1, T v2) {

    }

    public void testMethod() {
        final GenericsTest<T> test = new GenericsTest<>();
        test.doSomething(new Integer(0), new Integer(1));
    }

Like suggested, I will try to make things more clear with an anti-example:

As the test() method is inside the generic class, the T parameter used inside the method is the parameter of the class. This means, a new GenericTest<Double>().test() would create a GenericTest<Double> inside, while a new GenericTest<Integer>().test() would create a nice GenericTest<Integer> inside. As at compile-time it is unclear which concrete type for the T parameter will be used, the compiler raises the error when concrete types like Integer are used with the GenericTest<T> object created inside the test() method.

It would be perfectly fine to call new GenericTest<Integer>() within the test() method, but still a little bit confusing. This is why I would recommend to put such test methods outside the class, where such things become immediately clear.

(The answer moving the test code to a main() method does exactly that.)

It's not applicable because T is some subtype of Number . Ie it can be Double too. But, you can specify the T at constructor invocation:

    public void test()
    {
        GenericsTest<Integer> test = new GenericsTest<>();
        test.doSomething(new Integer(0), new Integer(1)); //Okay now
    }

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