简体   繁体   English

orElse 中的 Lambda 在有界通配符泛型中获取

[英]Lambda inside orElseGet in bounded wildcard generics

Part of my code looks like this:我的部分代码如下所示:

EntityTypeEnum entityType = EntityTypeEnum.fromName(entityTypeName).orElseThrow(...);
EntityService<? extends AbstractEntityDto> entityService = entityServiceFactory.getEntityService(importType);

return getFooArgs(bar)
    .map(entityService::getListWithFooArgs)
    .orElseGet(()->entityService.getListNoArgs());

There is an enum by which I obtain service class using static method from entityServiceFactory .有一个枚举,我通过它使用entityServiceFactory 的静态方法获取服务类。 Then I invoke method getFooArgs(...) , that returns Optional< FooArg > .然后我调用方法getFooArgs(...) ,它返回Optional< FooArg > Then I'd like to map it using EntityService method or use a method without args to obtain "default" value, when getFooArgs return empty Optional.然后我想使用EntityService方法映射它或使用没有 args 的方法来获取“默认”值,当getFooArgs返回空可选。

public interface EntityService<T extends AbstractEntityDto> {
    List<T> getListNoArgs();
    List<T> getListWithFooArgs(FooArg fooArgs);
}

Sadly I get Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto>遗憾的是,我Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto>得到了Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto> Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto> Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto> from my IDE.从我的 IDE Bad return type in lambda expression: List<capture of ? extends AbstractEntityDto> cannot be converted to List<capture of ? extends AbstractEntityDto> What I have to do is:我必须做的是:

Optional<List<? extends AbstractEntityDto>> listOptional = getFooArgs(bar)
        .map(entityService::getListWithFooArgs);

if(listOptional.isPresent())
    return listOptional.get();
else
    return entityService.getListNoArgs();

Can you explain why does it happen?你能解释为什么会这样吗? I assume it's soemthing related to ?我认为它与? and generics, but I thought that by using ?和泛型,但我认为通过使用? a lot of type's restrictions would disappear.许多类型的限制将消失。 If there is too little of code to figure it out, please let me know.如果代码太少而无法弄清楚,请告诉我。

I do not even try to find out why the compiler does not accept this construct.我什至不去找出为什么编译器不接受这个构造。 When it comes to type inference and wildcards, lots of things that look like they should work, don't.当涉及到类型推断和通配符时,很多看起来应该工作的东西,却没有。

The easiest fix is to provide an explicit type for the generic invocation of map :最简单的解决方法是为map的泛型调用提供一个显式类型:

return getFooArgs(bar)
    .<List<? extends AbstractEntityDto>>map(entityService::getListWithFooArgs)
    .orElseGet(entityService::getListNoArgs);

Generally, you should avoid wildcards in return types .通常,您应该避免在返回类型中使用通配符 There is no value in carrying the wildcard around.随身携带通配符没有任何价值。 In contrast, when you truly have code dealing with List<ConcreteEntityDto> and need to pass it to a method which should be able to deal with more cases, declaring a parameter type with a wildcard, like List<? extends AbstractEntityDto>相反,当您真正有处理List<ConcreteEntityDto>代码并且需要将其传递给应该能够处理更多情况的方法时,使用通配符声明参数类型,例如List<? extends AbstractEntityDto> List<? extends AbstractEntityDto> , to accept the List<ConcreteEntityDto> and also List<SomeOtherEntityDto> , is quiet useful. List<? extends AbstractEntityDto> ,接受List<ConcreteEntityDto>List<SomeOtherEntityDto> ,非常有用。

Note that given a请注意,给定一个

List<? extends AbstractEntityDto> list = …

you can do你可以做

List<AbstractEntityDto> view = Collections.unmodifiableList(list);

for subsequent processing which doesn't attempt to modify the list.用于不尝试修改列表的后续处理。 The wrapper returned by unmodifiableList prevents any attempt to insert elements into the list of unknown subtype of AbstractEntityDto but can guaranty to return instances of AbstractEntityDto for all query methods. unmodifiableList返回的包装器可防止任何将元素插入AbstractEntityDto的未知子类型列表的尝试,但可以保证为所有查询方法返回AbstractEntityDto实例。 That's why this type change is valid.这就是这种类型更改有效的原因。

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

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