我对 Java 泛型/模板参数和类型推断有疑问。特别是,我收到一个我不理解的编译错误(问题 3)。该代码使用 Android API。因此,有关 Android API 的一些背景知识可能有助于读者理解问题。我使用 Java 7。
我的存储库类:
public class MyEntity {}
public class MyRepository {
@NonNull final protected TreeMap< Long, MutableLiveData<ArrayList<MyEntity>> > liveEntitiesByID;
@NonNull
public LiveData<? extends List<MyEntity>> getEntitiesByID( long id ) {
return liveEntitiesByID.get( id );
}
}
为了在未来的版本中提供稳定的接口, 的接口MyRepository
应仅公开LiveData
包含 a的接口List
,但不应公开List
由 实际实现的接口ArrayList
。
问题一:为什么接口声明public LiveData<List<MyEntity>> getEntitiesByID( long id )
会导致“类型不兼容”?为什么我必须使用那种复杂的? extends List<MyEntity>
结构?
MutableLiveData
可以向上转换为LiveData
也ArrayList
可以向上转换为List
. 在这两种情况下,“is-an”关系都得到了满足。
我的视图模型类:
public class MyViewModel extends AndroidViewModel {
static private final String idKey = "id";
private final LiveData<Long> liveID;
private final LiveData<? extends List<MyEntity> liveEntities;
public LocalFolderViewModel( final Application application, @NonNull SavedStateHandle handle ) {
super( application );
myRepository = MyRepository.getInstance();
liveID = handle.getLiveData( idKey );
Function<Long, LiveData<? extends List<MyEntity>>> switchMap =
new Function<Long, LiveData<? extends List<MyEntity>>>() {
@Override
public LiveData<? extends List<MyEntity>> apply( Long id ) {
return myRepository.getEntitiesByID( id );
}
};
// Compilation error
liveEntities = Transformations.switchMap( liveID, switchMap );
}
}
问题 2:为什么我必须在它? extends List<MyEntity>
的定义中的任何地方都使用结构Function<Long, LiveData<? extends List<MyEntity>>> ...
,如果可以简单地写成List<MyEntity>
. (可能与问题 1 相同的问题/解释。)
编译失败并Transformations.switchMap( liveID, switchMap )
出现错误
method switchMap in class Transformations cannot be applied to given types
required: LiveData<X>,Function<X,LiveData<Y>>
found: LiveData<Long>,Function<Long,LiveData<? extends List<LocalImageID>>>
reason: cannot infer type-variable(s) X,Y
(argument mismatch; Function<Long,LiveData<? extends List<LocalImageID>>> cannot be converted to Function<X,LiveData<Y>>)
问题3:我该如何解决这个问题?恕我直言,类型应该匹配。
虽然我会理解问题 1 和 2 可能是 Java 语言的固有限制,但我没有看到问题 3。特别是,我尝试了其他几种变体,但都没有奏效。似乎我不了解泛型/模板参数在 Java 中的基本工作原理。我是一个相当优秀的 C++17/20 程序员,并且在模板参数方面从来没有遇到过问题,但是 Java 让我发疯了。