Jer*_*emy 18 java type-erasure
假设我的课程中有两个构造函数:
public User (List<Source1> source){
...
}
public User (List<Source2> source) {
...
}
Run Code Online (Sandbox Code Playgroud)
假设这两个构造函数都提供了有关用户的相同信息,并且是为不同用例构建用户的同等有效方法.
在Java中,由于类型擦除而无法执行此操作 - Java不会接受两个具有作为参数List <?的构造函数.>.
那么,解决这个问题的方法是什么?什么是不是矫枉过正但仍然尊重基本OO的解决方案?由于Java没有强大的泛型支持,因此必须构建一个工厂方法或其他接口似乎是错误的.
以下是我能想到的可能性:
1)接受a List<?>作为构造函数的参数,并在构造函数中解析您需要哪种逻辑,或者如果它不是任何可接受的类型则抛出异常.
2)创建一个接受List的类,构造相应的User对象,并返回它.
3)创建包装器,List<Source1>然后List<Source2>可以将其传递给User构造函数.
4)使用两个类对这个人进行子类化,其中除了构造函数之外,所有的功能都是继承的.一个的构造函数接受Source1,另一个接受Source2.
5)用一个构建器包装这个人,其中两个不同的构建器方法用于实例化两个不同的数据源.
我的问题是这些:
1)是否需要使用Java或有意的设计决策来做这个缺陷?什么是直觉?
2)在保持良好代码而不引入不必要的复杂性方面哪种解决方案最强?为什么?
这个问题是类似的:在Java中围绕类型擦除设计构造函数但没有详细说明,它只是提出了各种解决方法.
通常的方法是使用工厂方法:
public static User createFromSource1(List<Source1> source) {
User user = new User();
// build your User object knowing you have Source1 data
return user;
}
public static User createFromSource2(List<Source2> source) {
User user = new User();
// build your User object knowing you have Source2 data
return user;
}
Run Code Online (Sandbox Code Playgroud)
如果你只需要使用建筑Source1或Source2(即你没有一个默认的构造函数),您只需隐藏你的构造函数,强制客户端使用你的工厂方法:
private User () {
// Hide the constructor
}
Run Code Online (Sandbox Code Playgroud)
出现这个问题是因为你不能以不同的方式命名构造函数,如果这些是正常的方法,那就是你如何克服它.因为构造函数名称被固定为类名,所以这种代码模式只能区分,然后给出相同类型的擦除.
| 归档时间: |
|
| 查看次数: |
3581 次 |
| 最近记录: |