简体   繁体   English

静态泛型方法的返回类型能否取决于其参数?

[英]Can the return type of a static generic method depend on its arguments?

I "simply" want to write a static generic method that takes the generic Collection<E> of any type E as its input, and outputs a result of the appropriate type Vector<E> . 我“简单地”想要编写一个静态的泛型方法,该方法将任何类型E的泛型Collection<E>作为其输入,并输出适当类型Vector<E> Since the type E is always known at compile-time, this should not be a problem - but it is... Thus, a call should later look like: 由于类型E在编译时始终是已知的,因此这应该不是问题-而是...因此,以后的调用应类似于:

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

Here is what I tried - all without success: 这是我尝试过的-都没有成功:

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

Is this not possible at all? 这根本不可能吗? And if not, is there a good reason why not? 如果没有,是否有充分的理由为什么不呢? Or am I just doing it wrong? 还是我做错了? Probably there is some solution using Lambda expressions? 可能有一些使用Lambda表达式的解决方案?

You should give your static method its own generic type parameter : 您应该给静态方法自己的泛型类型参数:

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

You were missing the generic type parameter declaration ( <T> ) before the return type of the method. 在方法的返回类型之前,缺少通用类型参数声明( <T> )。

From the JDK documentation: "For static generic methods, the type parameter section must appear before the method's return type.". 从JDK文档中:“对于静态泛型方法,类型参数部分必须出现在方法的返回类型之前。” So it should look like 所以应该看起来像

public static <E> Vector<E> toVector1(Collection<E> coll) {
    return new Vector<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>();
}

This is because you've already defined a type-parameter, called E , on instance context and the compiler doesn't allow you to use it on static context. 这是因为您已经在实例上下文中定义了一个名为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>();
}

Here, even though you don't use the instance type-parameter E , but another one, called X , the former is not correctly defined. 在这里,即使您没有使用实例类型参数E ,但另一个实例X却没有正确定义。 When introducing method-scoped type-parameters, you have to do: 引入方法范围的类型参数时,您必须执行以下操作:

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

The error is simply because the wildcard <?> can be only used in return-types and on initialization, but not on instantiation (like you've done). 该错误仅是因为通配符<?>只能用于返回类型和初始化,而不能用于实例化(如您所做的那样)。


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

The reason is the same as 1st try. 原因与第一次尝试相同。 You can fix this by having: 您可以通过以下方法解决此问题:

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

However, note that when you use this method, you won't be able to add anything but null to the resulting list. 但是,请注意,使用此方法时,除了将null 添加到结果列表之外,将无法添加其他任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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