静态通用方法

Ton*_*ony 29 java generics

你能解释为什么以下有效吗?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

T v1, T v2应该是相同的类型doSomethingStatic,但我仍然能够传递不同的类型(整数和字符串).

如果doSomethingStatic()默认采用普通超类,为什么不能doSomethingStaticList()使用不同类型?

Jar*_*lak 23

在非静态情况下,您定义TString创建实例的时间GenericsTest.因此传递一个int将给出编译错误.如果你这样gt.doSomething(1, 2)做也会失败.

在静态情况下,您不T手动定义,它是从参数派生的.它将是这两个类的第一个常见超类 - 在这种情况下是Object.您可能想要使用有界通配符,例如<T extends Number><T extends CharSequence>.

请注意,这里有两个不同T的:

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

泛型参数的声明就是你写的时候<T>.在这种情况下,您可以使用不同的字母以避免混淆.


Phi*_*nov 14

这工作,因为T在静态方法是他自己的类型参数,而不是T参数的情况下,在您使用的成员方法.重命名以澄清:

public static class GenericsTest<T> {

    public void doSomething(T v1, T v2) {

    }

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

    }
//...
Run Code Online (Sandbox Code Playgroud)

因此,如果doSomething(...)你的实例类型参数值是String这样,那就是一个错误.如果doSomethingStatic(...)类型参数的静态值不同:

GenericsTest.doSomethingStatic(1, "abc"); //ok
GenericsTest.<Object>doSomethingStatic(1, "abc"); //ok
GenericsTest.<String>doSomethingStatic(1, "abc"); //not ok
new GenericsTest<String>().doSomething(1, "abc"); //not ok
Run Code Online (Sandbox Code Playgroud)