Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用通配符的泛型方法调用_Java_Generics - Fatal编程技术网

Java 使用通配符的泛型方法调用

Java 使用通配符的泛型方法调用,java,generics,Java,Generics,我有一个方法submit: <T> Future<Optional<T>> submit(Value<T> value) { //... } 也可以编译,但在返回值之前,我需要对E执行不安全的强制转换 这里有一个解释泛型不变性的答案,但它仍然没有回答如何使用捕获的类型 据我所知,没有办法告诉编译器您的代码实际上是正确的。您可以尝试用对象替换?: Value<Object> value = null; Future<Opt

我有一个方法
submit

<T> Future<Optional<T>> submit(Value<T> value) {
    //...
}
也可以编译,但在返回值之前,我需要对E执行不安全的强制转换

这里有一个解释泛型不变性的答案,但它仍然没有回答如何使用捕获的类型


据我所知,没有办法告诉编译器您的代码实际上是正确的。您可以尝试用
对象替换

Value<Object> value = null;
Future<Optional<Object>> future = submit(value);
Value=null;
未来=提交(值);

我看不出问题真正出在哪里

Future<? extends Optional<?>> future = submit(value);
Optional<?> f = future.get();
Future>Future=submit(值);
可选f=future.get();
正确编译和运行

您链接的答案非常清楚地解释了这一点:

Foo
是一个
Foo

但是


Foo
不是
Foo您可以更改方法以使用通配符运算符作为参数,因为您没有在
t
上指定任何类型。在我看来,这不会有多大变化

Future<Optional<?>> submit(Value<?> value) {
    //...
}     

Future虽然我不确定为什么将其用作
Future>
应该是个问题,但根据您愿意接受的扭曲和“技巧”的数量,可能会有一个解决方案


即使使用附加类型参数
E
,也不可能以所需的形式编译它,因为它不是类型安全的。至少,(对于编译器)不可能确保它是类型安全的。它不能是类型安全的原因可以总结如下:有人收到
未来为什么这是一个问题?就我所知,这没有实际的区别,
future.get()
将返回一个
可选的
对象。不幸的是
作为参数传递给我,我无法更改它的签名您可以将其转换为
。我认为ClassCastException的风险很低,因为不管实际的泛型是什么,它总是
对象
@mvieghofer的派生,你可以,但你不必。将
Foo
转换为
Foo
几乎肯定是设计错误的标志。@biziclop我同意你的观点,但我也认为将
传递给任何方法(这里似乎是这样)也是一种糟糕的设计。最好的方法是去掉
参数。@mvieghofer那么呢?传递无界通配符参数通常是设计不好的标志,但它有其合法用途。当然,它会有很大的变化,因为在
版本中,输入参数的类型不必与返回值匹配。因此,您可以将
Value
传递给该方法,但返回
Future
,这可能不是该方法应该做的。submit方法应该是类型化的,这意味着返回类型和参数类型应该匹配是的,我知道,但他在他的示例中没有这样做,这意味着他不关心具体的回报类型。这就是为什么我写到在这种情况下变化不大。如果你说你需要匹配参数,那么为什么你没有用一个特定的参数传递
value
,而不是通配符运算符?问题是可选实际上是可选的,我希望有一种方法可以告诉编译器不要在方法签名或方法调用中,以便
未来的
签名可以保留可选性这就是告诉它的方法。
列表
示例向您展示了原因。为什么带有
E
的代码段可以工作?在这种情况下,它看起来像?不是captured@user2961393因为
E
必须绑定到特定的类,该类在整个表达式中具有相同的值。而
字面意思是任何东西都可以进入那里。我仍然不明白你为什么要进行不安全的强制转换来避免正确的符号。你的例子只是更改了future的签名,使其与future匹配?如果仍然捕获,则应该有一个更干净的解决方案,它不需要“松散”未来的类型,即未来的代码
Future<? extends Optional<?>> future = submit(value);
Optional<?> f = future.get();
Future<Optional<?>> submit(Value<?> value) {
    //...
}     
List<Integer> integers = new ArrayList<Integer>();
List<Number> numbers = Collections.unmodifiableList(integers);
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class GenericOptionalFutureMethod
{
    void call()
    {
        Value<?> value = null;
        Future<Optional<?>> future = 
            FutureWrapper.<Optional<?>>wrap(submit(value));
    }

    <T> Future<Optional<T>> submit(Value<T> value) {
        return null;
    }
}

class FutureWrapper 
{
    static <T> Future<T> wrap(final Future<? extends T> future)
    {
        return new Future<T>()
        {
            @Override
            public boolean cancel(boolean mayInterruptIfRunning)
            {
                return future.cancel(mayInterruptIfRunning);
            }

            @Override
            public boolean isCancelled()
            {
                return future.isCancelled();
            }

            @Override
            public boolean isDone()
            {
                return future.isDone();
            }

            @Override
            public T get() throws InterruptedException, ExecutionException
            {
                return future.get();
            }

            @Override
            public T get(long timeout, TimeUnit unit)
                throws InterruptedException, ExecutionException,
                TimeoutException
            {
                return future.get();
            }
        };
    }

}