静态泛型方法的返回类型是否可以依赖于它的参数?

时间:2015-07-01 09:22:58

标签: java generics

我&#34;简单地说&#34;想要编写一个静态泛型方法,该方法将任何类型Collection<E>的泛型E作为其输入,并输出相应类型Vector<E>的结果。由于类型E在编译时始终是已知的,因此这应该不是问题 - 但它是......因此,稍后调用应该如下:

Collection<String> coll = ...
Vector<String> vec = Convert.toVector(coll); // either this or...
Vector<String> vec = Convert<String>.toVector(coll);

这是我尝试过的 - 都没有成功:

import java.util.Collection;
import java.util.Vector;

public class Convert<E> {

    // 1st try, same type E as class => Error: Cannot make a static reference to the non-static type E
    public static Vector<E> toVector1(Collection<E> coll) {
        return new Vector<E>();
    }

    // 2nd try, a new type X. => Error: X cannot be resolved to a type
    public static Vector<X> toVector2(Collection<X> coll) {
        return new Vector<X>();
    }

    // 3rd try, using wildcard. => Error: Cannot instantiate the type Vector<?> 
    public static Vector<?> toVector3(Collection<?> coll) {
        return new Vector<?>();
    }

    // 4th try, using bounded wildcard. => Error: Cannot make a static reference to the non-static type E
    public static Vector<? extends E> toVector4(Collection<? extends E> coll) {
        return new Vector<E>();
    }
}

这根本不可能吗?如果没有,有什么理由不是吗?或者我只是做错了?可能有一些使用Lambda表达式的解决方案?

3 个答案:

答案 0 :(得分:4)

您应该为静态方法提供自己的泛型类型参数:

<T>

在方法的返回类型之前,您缺少泛型类型参数声明(<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script> )。

答案 1 :(得分:3)

从JDK文档:&#34;对于静态泛型方法,类型参数部分必须出现在方法的返回类型之前。&#34;。所以看起来应该是

public static <E> Vector<E> toVector1(Collection<E> coll) {
    return new Vector<E>();
}

答案 2 :(得分:2)

// 1st try, same type E as class => Error: Cannot make a static reference to the non-static type E
public static Vector<E> toVector1(Collection<E> coll) {
    return new Vector<E>();
}

这是因为您已经在实例上下文中定义了一个名为E的类型参数,并且编译器不允许您在静态上下文中使用它。

// 2nd try, a new type X. => Error: X cannot be resolved to a type
public static Vector<X> toVector2(Collection<X> coll) {
    return new Vector<X>();
}

在这里,即使您不使用实例类型参数E,但另一个名为X,但前者未正确定义。在引入方法范围的类型参数时,您必须执行以下操作:

public static <X> Vector<X> toVector2(Collection<X> coll) {
    return new Vector<X>();
}
// 3rd try, using wildcard. => Error: Cannot instantiate the type Vector<?> 
public static Vector<?> toVector3(Collection<?> coll) {
    return new Vector<?>();
}

错误只是因为通配符<?>只能用于返回类型和初始化,而不能用于实例化(就像你已经完成的那样)。

// 4th try, using bounded wildcard. => Error: Cannot make a static reference to the non-static type E
public static Vector<? extends E> toVector4(Collection<? extends E> coll) {
    return new Vector<E>();
}

原因与第一次尝试相同。您可以通过以下方式解决此问题:

public static <X> Vector<? extends X> toVector4(Collection<? extends X> coll) {
    return new Vector<X>();
}

但是,请注意,当您使用此方法时,您无法将<{1}}之外的任何内容添加到结果列表中。