Java 编译器能否通过泛型方法验证对象的泛型类型?
首先,为这个糟糕的标题感到抱歉。我不知道如何用几句话来描述这个问题(也许不是很多) 我正在重构我们系统中的一些设置,使之更加抽象。当前解决方案在数据库中有多个表,每个设置区域一个表。为了添加一个新的设置,您需要扩展模式、hibernate类、所有传输对象类、getter/setter等。我觉得这违反了OCP(开-闭原则),因此需要重构 我花了一些时间想出了如何实现这种抽象的想法。到目前为止,我最喜欢的想法如下:Java 编译器能否通过泛型方法验证对象的泛型类型?,java,generics,enums,Java,Generics,Enums,首先,为这个糟糕的标题感到抱歉。我不知道如何用几句话来描述这个问题(也许不是很多) 我正在重构我们系统中的一些设置,使之更加抽象。当前解决方案在数据库中有多个表,每个设置区域一个表。为了添加一个新的设置,您需要扩展模式、hibernate类、所有传输对象类、getter/setter等。我觉得这违反了OCP(开-闭原则),因此需要重构 我花了一些时间想出了如何实现这种抽象的想法。到目前为止,我最喜欢的想法如下: public class SettingDefinition<T> {
public class SettingDefinition<T> {
private String name;
private T defaultValue;
public SettingDefinition(String name, T defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
}
public String getName() {
return name;
}
public T getDefaultValue() {
return defaultValue;
}
}
- 每个设置区域1个枚举
- 每个设置1个枚举值
- 每个设置都是一个使用泛型类型的
设置定义
类
正在使用泛型类型的静态get/set方法设置服务
public enum SettingsABC{
A(new SettingDefinition<Integer>("A", 123)),
B(new SettingDefinition<String>("B", "Hello")),
C(new SettingDefinition<Boolean>("C", false));
private SettingDefinition settingDefinition;
SettingsABC(SettingDefinition settingDefinition) {
this.settingDefinition = settingDefinition;
}
public SettingDefinition getDefinition() {
return settingDefinition;
}
}
获取/设置值的服务将是:
public class SettingsService {
public static <T> T getSetting(SettingDefinition setting) {
// hit db to read
// return value
}
public static <T> void setSetting(SettingDefinition setting, T value) {
// hit db to write
}
}
我的问题是,我无法在SettingDefinition
内部SettingsABC
的泛型类型和服务的get/set方法的泛型类型之间执行编译器类型检查。所以本质上,我可以做到:
Integer value = SettingsService.getSetting(SettingsABC.B.getDefinition());
SettingsService.setSetting(SettingsABC.A.getDefinition(), "A");
其中B
的定义为字符串类型
此外,我可以这样做:
Integer value = SettingsService.getSetting(SettingsABC.B.getDefinition());
SettingsService.setSetting(SettingsABC.A.getDefinition(), "A");
其中,A
的定义是一个整数
有没有办法使用泛型强制这两种不同的泛型类型匹配?您可以将枚举转换为类:
public final class SettingsABC<T> {
public static final SettingsABC<Integer> A =
new SettingsABC<>(new SettingDefinition<>("A", 123));
public static final SettingsABC<String> B =
new SettingsABC<>(new SettingDefinition<>("B", "Hello"));
public static final SettingsABC<Boolean> C =
new SettingsABC<>(new SettingDefinition<>("C", false));
private final SettingDefinition<T> settingDefinition;
// private constructor, so nobody else would instantiate it
private SettingsABC(SettingDefinition<T> settingDefinition) {
this.settingDefinition = settingDefinition;
}
public SettingDefinition<T> getDefinition() {
return settingDefinition;
}
}
虽然它不再是枚举,但它的使用方式基本相同。如果您需要在enum中通常可用的其他方法,您可以这样模拟它们:
String value = SettingsService.getSetting(SettingsABC.B.getDefinition());
SettingsService.setSetting(SettingsABC.A.getDefinition(), 123);
public String name() {
return settingDefinition.getName();
}
@Override
public String toString() {
return settingDefinition.getName();
}
// and so on
publicstaticvoidsetsetting(settingdefinitionsetting,t value)
会起作用吗?我想会,但不会。我在泛型方面没有那么丰富的经验,所以我无法解释为什么不能。您需要自己存储/传递类。然后getter可以执行返回clazz.cast(值)代码>=您自己的类运行时存储。我看到原始类型!在描述泛型类时,切勿仅使用类型。即使是这样做的能力也是一种过时的向后兼容性混乱。您总是可以执行类似于GenericType
的操作。对不起,伙计,我不明白这将如何替换原始类型。你能再详细一点吗?谢谢,这似乎更接近我的想法。我会进一步调查的。