0

我对 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可以向上转换为LiveDataArrayList可以向上转换为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 让我发疯了。

4

0 回答 0