- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要 Java 泛型方面的帮助。我的模型是:我有一些扩展 Dto(数据传输对象)的类和一些扩展实体(我的对象模型到 DB)的类。我有
interface Mapper<D extends Dto, E extends Entity>{
//Convert a Entity to Dto.
D toDto(E entity);
我有一些实现此接口(interface)的类(即 PersonMapper、BookMapper 等等)。
@Component
public class PersonMapper implements Mapper<PersonDto, PersonEntity> {
//implementation
}
@Component
public class BookMapper implements Mapper<BookDto, BookEntity> {
//implementation
}
我想做的是使用工厂模式以便在运行时选择我的映射器,这取决于我传入输入的字符串。
@Autowired
private PersonMapper personMapper;
@Autowired
private BookMapper bookMapper;
public <D extends Dto, E extends Entity> Mapper<D, E> selectMapper(String entity){
if ("Person".equalsIgnoreCase(entity))
return personMapper;
if("Book".equalsIgnoreCase(entity))
return bookMapper;
...
}
在这种情况下,我有以下编译错误:
Type mismatch: cannot convert from PersonMapper to Mapper<D,E>
我的解决方案:
1)
return (Mapper<D, E>) personMapper;
但我有一个警告:
Type Safety: `Unchecked class from personMapper to Mapper<D,H>`
2)
使用 WildCard 和 castingb
public Mapper<Dto, Entity> selectMapper(String entity){
Mapper<? extends Dto, ? extends Entity> toReturn = null;
if ("Person".equalsIgnoreCase(entity))
toReturn = personMapper;
else if("Book".equalsIgnoreCase(entity))
toReturn = bookMapper;
...
return (Mapper<Dto, Entity>) toReturn;
}
但在这种情况下我还有一次警告:
Type safety: Unchecked cast from Mapper<capture#29-of ? extends Dto,capture#30-of ? extends Entity> to Mapper<Dto,Entity>
它有效,但它似乎不是一个干净的解决方案
3) 使用通配符作为返回类型:
public Mapper<? extends Dto, ? extends HistoryEntity> selectMapper(String entity)
但是你知道,根本不推荐使用通配符作为返回类型,这对我也没有帮助,因为我想使用这个映射器并调用 mapper.toDto 确保返回类型是扩展 Dto 的东西。
============================================ ==========================
我不解释为什么要写这样的类构造器
public Service<D extends Dto, E extends Entity>{
public Service(Mapper<D,E> mapper){
this.mapper = mapper;
}
}
然后我注入(inject)(例如)bookMapper 它起作用了。
相反,如果 Mapper
============================================ ==========================
我请求你的帮助是:
我如何使用干净的代码原则(避免编译警告、sonarlint 问题等)编写解决方案以实现这种逻辑?
非常感谢,如果您花一点时间帮助我解决我的问题,我将不胜感激。
最佳答案
那些关于调用者而不是你的代码的变量(D 和 E)。 D和E是由调用者决定的,所以绝对没有办法保证PersonDTO
。适合。
制作Mapper<? extends DTO, ? extends Entity>
(并且没有变量),并且鉴于这些已经是下限,只是 Mapper<?, ?>
- 那行得通,你可以写你的 return
没有任何强制转换且没有编译器错误或警告的语句。
当然,这意味着调用者有一个几乎无用的类型。
泛型完全基于“编译时/写入时”。 JVM ( java.exe
) 不知道泛型是什么,事实上它们中的大多数都无法在编译过程中存活下来。 泛型的唯一目的是让编译器标记不正确的代码并避免某些类型转换,仅此而已。
将该字符串转换为 Mapper 的本质完全是运行时的。
因此,如果 Mapper<?, ?>
还不够,你想要的是不可能的。你需要编写编译/写入时可检查的东西,所以当你使用字符串时,这是不可能的。例如,一个方法 getPersonMapper()
当然可以返回 Mapper<PersonDTO, PersonEntity>
,没问题。
更笼统地说(嘿),听起来您在这里糟糕地重新发明了各种轮子。查看 JDBI、JOOQ 和 Hibernate 的教程,了解通常如何编写与数据库交互的 Java 代码。
关于java - 使用泛型在 Java 中实现工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70637259/
我是一名优秀的程序员,十分优秀!