Android:泛型中的接口继承

时间:2021-04-29 09:00:28

标签: java

我需要为不同的接口创建数据库对象,从 MyInterface 继承,但 Java 假设“接口”是一个类,然后我在 create() 方法的声明“”中得到编译错误。什么是正确的解决方案?

public interface MyInterface {
}

public interface DbDictionaries extends MyInterface {
}

public interface DBDocuments extends MyInterface {
}

@Database(entities = {}, version = 1, exportSchema = false)
public abstract class DbDictionaries_v1 extends RoomDatabase implements DbDictionaries {
}

@Database(entities = {}, version = 1, exportSchema = false)
public abstract class DBDocuments_v1 extends RoomDatabase implements DBDocuments {
}

public class Database<Interface extends MyInterface> {
    private final WeakReference<Context> context;
    private Interface instance = null;

    public Database(Context context) {
        this.context = new WeakReference<Context>(context);
    }
    
    /* ERROR: unexpected type, required: class, found: type parameter Interface */
    public <E extends RoomDatabase & Interface> void create(@NonNull Class<E> version, @NonNull String name) {
        instance = (Interface)androidx.room.Room.databaseBuilder(context.get(), version, name)
                .allowMainThreadQueries()
                .build();
    }

    public Interface db() {
        return instance;
    }
}

可以将声明替换为“”,但会导致警告:“unchecked typecast”,因为可以这样写:

Database<DbDictionaries> dictionaries = new Database<DbDictionaries>(this);

但是:

dictionaries.create(DBDocuments_v1.class, "Dictionaries_db");

-- 这是不正确的,因为 DBDocuments 没有扩展 DbDictionaries 接口。

(更新)

毕竟,工作代码是:

@SuppressWarnings("unchecked") // Because "<E extends RoomDatabase & DbInterface>" does not allowed in java
public boolean create(@NonNull Class<? extends DbInterface> version, @NonNull String name) {
    try {
        close();
        instance = (DbInterface)androidx.room.Room.databaseBuilder(
                /* Typecast here is very important thing */
                context.get(), version.asSubclass(BaseClass.class), name)
                .allowMainThreadQueries().enableMultiInstanceInvalidation()
                .addMigrations(migrations)
                .build();
        filename = name;
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

1 个答案:

答案 0 :(得分:0)

您可以添加一个扩展 Roomdatabase 并实现 MyInterface

的小层类
public abstract class MyRoomDatabase extends RoomDataBase implements MyInterface {

并更改您的其他课程:

public abstract class DbDictionaries_v1 extends MyRoomDatabase implements DbDictionaries {

所以如果你有条件 <E extends MyRoomDatabase>,它肯定会实现 MyInterface


但要解决您的问题,您必须在 E 方法中删除 ? 并将其替换为 create

public void create(@NonNull Class<? extends Interface> version, @NonNull String name) {

与:

public abstract class DbDictionaries_v2 extends RoomDatabase implements DbDictionaries {

你可以这样做:

    Database<DbDictionaries> dictionariesv1 = new Database(new Context());
    dictionariesv1.create(Database.DbDictionaries_v1.class, "Dictionaries_db");
    dictionariesv1.db(); // return a DbDictionaries class
    
    Database<DbDictionaries> dictionariesv2 = new Database(new Context());
    dictionariesv2.create(Database.DbDictionaries_v2.class, "Dictionaries_db");
    dictionariesv2.db(); // return a DbDictionaries class

    Database<DbDictionaries> documentv1 = new Database(new Context());
    // Compilation error here 
    documentv1.create(Database.DBDocuments_v1.class, "Dictionaries_db");
    documentv1.db();

抱歉我没有Android代码,我添加了一个空的类Context用于代码编译