我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表示资源 ID。
资源 ID 的当前方法:
interface ResourceId {
T get();
}
class UserId implements ResourceId {
public String get();
}
我们资源/模型的当前方法:
interface Resource {
I id();
}
class User implements Resource {
public UserId id();
}
我正在努力为我们的 DAO 类寻找一个可行的解决方案。以下是我尝试但失败的一些方法:
=== 选项 1 ===
失败:
error: > expected
Java 中似乎禁止多级泛型类型
interface Dao> {
R findById(I id);
void save(R u);
}
class UserDao implements Dao {
public User findById(UserId id);
public void save(User u);
}
=== 选项 2 ===
失败:
UserDao is not abstract and does not override abstract method save(R) in Dao
Dao
看起来也很愚蠢。 UserDao 应该是一个 Dao
对象。
interface Dao {
> R findById(I id);
> void save(R u);
}
class UserDao implements Dao {
public User findById(UserId id);
public void save(User u);
}
=== 选项 3 ===
失败:
UserDao is not abstract and does not override abstract method findById(I) in Dao
即使有效,我也不受 R 实际实现的 ResourceId 的约束。
interface Dao {
R findById(I id);
void save(R u);
}
class UserDao implements Dao {
public User findById(UserId id);
public void save(User u);
}
=== 选项 4 ===
Biên dịch.
但是,UserDao 中的#findById 必须采用 ResourceId 类型的通用参数,而不是 UserId。此外,在#findById 的实现中,我们必须将#get() 的结果转换为字符串。
通常问题是 ResourceId 的类型不受 R 实际实现的 ResourceId 的约束。
interface Dao {
R findById(ResourceId id);
void save(R u);
}
class UserDao implements Dao {
public User findById(ResourceId id);
public void save(User u);
}
=== 选项 5 ===
Biên dịch.
然而 Dao
看起来很愚蠢。我们要使用的 ResourceId 的信息(即 UserId)在 Resource(即 User)的实现中已经可用。有没有更清洁的方法?
interface Dao {
R findById(I id);
void save(R u);
}
class UserDao implements Dao {
public User findById(UserId id);
public void save(User u);
}
有什么想法可以正确解决这个问题吗?
您的选项 # 1 可以通过适当调整来正常工作。首先添加 ResourceId
Dao
的通用类型规范声明:
static interface Dao, R extends Resource> {
R findById(I id);
void save(R u);
}
... 然后对 Dao
做同样的事情子类:
static class UserDao implements Dao {
public User findById(UserId id) { return null; }
public void save(User u) {}
}
因为您不需要知道 ResourceId
的通用类型是什么(
) 在 Resource
的上下文中类,你可以用通配符将其关闭:
static interface Resource> {
I id();
}
最后,完整的代码将编译为:
public class NestedGenerics {
static interface ResourceId {
T get();
}
static class UserId implements ResourceId {
public String get() { return null; }
}
static interface Resource> {
I id();
}
static class User implements Resource {
public UserId id() { return null; }
}
static interface Dao, R extends Resource> {
R findById(I id);
void save(R u);
}
static class UserDao implements Dao {
public User findById(UserId id) { return null; }
public void save(User u) {}
}
}
Complete code on GitHub
Hy vọng điều này sẽ giúp.
Tôi là một lập trình viên xuất sắc, rất giỏi!