简而言之:
我正在尝试使用 Java 流 + 映射函数来创建要作为响应实体返回的对象列表。但是编译器抱怨内部类的私有访问(尽管在其他情况下没有这样做)。
代码:
public class Donkey {
...
public DonkeyResponseEntity toResponseEntity() {
DonkeyResponseEntity dre = new DonkeyResponseEntity();
dre.id = this.id;
dre.name = this.name;
dre.numDonkeysInPossee = this.numDonkeysInPossee;
return dre;
}
private class DonkeyResponseEntity {
public Long id;
public String name;
public Integer numDonkeysInPossee;
}
}
public class DonkeyService {
...
public ResponseEntity<?> getDonkeys(List<Donkey> previousDonkeyList) {
...
List<Object> donkeyPossee = previousDonkeyList.stream()
.map(donkey -> donkey.toResponseEntity()).collect(Collectors.toList()); // !!ERROR HERE!!
return new ResponseEntity<>(donkeyPossee, HttpStatus.OK);
}
...
}
错误发生在带有
.map(donkey -> donkey.toResponseEntity())
的线路上。
为什么我感到困惑:
如果我写了类似下面的内容,就不会出现访问错误:
Object d = previousDonkeyList.get(0).toResponseEntity();
甚至
List<Object> donkeyPossee = previousDonkeyList.stream()
.filter(donkey -> donkey.toResponseEntity() == null);
要求:
有人可以解释为什么会发生这种情况吗?我不太清楚为什么
map
会对此提出异议。
澄清:
我不是在寻找替代方法来完成此任务(使用
forEach
并手动添加到 List
作品);我只是想知道为什么map
不批准。
这里的差异来自于以下事实:
map
类中的Stream
方法实际上使用从映射函数返回的对象的类型 - 在本例中是DonkeyResponseEntity
。
filter
方法不会以任何方式对实际类型进行操作,仅对对象实例进行操作(验证引用是否指向
null
并且返回布尔值)。从列表中获取第一个元素时,您也不引用 type,因为引用的类型为
Object
:
// no error
Object d = previousDonkeyList.get(0).toResponseEntity();
如果您要使用DonkeyResponseEntity
类型的引用,编译器也会将其标记为错误:
// error
DonkeyResponseEntity d = previousDonkeyList.get(0).toResponseEntity();
有趣的是,如果您使用var
,编译器不会将其标记为错误,因为没有使用显式的私有类型:
// no error
var d = previousDonkeyList.get(0).toResponseEntity();
但即使私有类有公共方法,你也无法访问它们。如果您在
map
方法中转换返回的对象,编译器不会将其标记为错误,因为它不需要知道(“查看” - 有权访问)对象的实际类型:
// no error
.map(donkey -> (Object) donkey.toResponseEntity())