Static generic methods

Tony :

Can you explain why the following works?

public class GenericsTest<T> {

    public void doSomething(T v1, T v2) {

    }

    public static <T> void doSomethingStatic(T v1, T v2) {

    }

    public static <T> void doSomethingStaticList(List<T> v1, List<T> v2)
    {

    }

    public static void main(String[] args) {
        GenericsTest<String> gt = new GenericsTest<>();

        // OK
        gt.doSomething("abc", "abc");

        // Not OK
        gt.doSomething(1, "abc");

        // OK
        doSomethingStatic(1, 2);

        // Still OK
        doSomethingStatic(1, "abc");

        // So why is this not OK?
        List<String> list1=new LinkedList<>();
        List<Integer> list2=new LinkedList<>();
        doSomethingStaticList(list1,list2);
    }
}

T v1, T v2 should be the same type in doSomethingStatic, but I'm still able to pass different types(integer and string).

If doSomethingStatic() takes a common super class by default, why doesn't doSomethingStaticList() work with different types?

Jaroslaw Pawlak :

In non-static case you define T as String when you create instance of GenericsTest. Hence passing an int will give compile error. If you did gt.doSomething(1, 2) it would fail as well.

In static case, you don't define T manually, it is derived from parameters. It will be the first common superclass of both classes - which in this case is Object. You might want to use bounded wildcard, e.g. <T extends Number> or <T extends CharSequence>.

Note that you have two different Ts here:

  • GenericsTest<T>
  • public static <T> void doSomethingStatic(T v1, T v2)

The declaration of generic parameter is whenever you write <T>. You can use different letters in this case to avoid confusion.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=420880&siteId=1