它有可能设计一种在编译时调用不同方法重载的方法吗?可以说,我有这个小班:@RequiredArgsConstructorpublic class BaseValidator<T> { private final T newValue;}现在,我需要返回不同对象的方法(取决于T)。像这样:private StringValidator getValidator() { return new ValidationString(newValue);}private IntegerValidator getValidator() { return new Validation(newValue);}最后,我想要一个非常流畅的呼叫层次结构,如下所示:new BaseValidator("string") .getValidator() // which returns now at compile-time a StringValidator .checkIsNotEmpty();//ornew BaseValidator(43) .getValidator() // which returns now a IntegerValidator .checkIsBiggerThan(42);在我的“真实”情况下(我有一种非常具体的方式来更新对象,并且每个对象都有很多条件,并且存在复制和粘贴问题的可能性很高。因此,该向导强制所有开发人员实施完全这边走。) :我尝试了不同的方式。验证程序内部的复杂泛型,或使用泛型。我的最后一个审批程序如下所示。public <C> C getValidator() { return (C) getValidation(newValue);}private ValidationString getValidation(String newValue) { return new StringValidator(newValue);}private ValidationInteger getValidation(Integer newValue) { return new IntegerValidation(newValue);}诀窍是什么?// edit:我希望在编译时使用它,而不是在运行时使用instanceof -checks。 最佳答案 诀窍是什么?不要这样做。提供静态工厂方法:class BaseValidator<T> { static ValidationString getValidation(String newValue) { return new ValidationString(newValue); } static ValidationInteger getValidation(Integer newValue) { return new ValidationInteger(newValue); }}class ValidationString extends BaseValidator<String> { ... }class ValidationInteger extends BaseValidator<Integer> { ... }尽管我认为这很奇怪:您是在基类内部引用子类。这样的循环依赖性使代码难以使用,尤其是在重构时,甚至在初始化时。相反,我建议创建一个包含工厂方法的实用程序类:class Validators { private Validators() {} static ValidationString getValidation(String newValue) { return new ValidationString(newValue); } static ValidationInteger getValidation(Integer newValue) { return new ValidationInteger(newValue); }}没有这样的周期。关于泛型,真正重要的一点是,它无非就是将显式强制转换隐式化(然后检查所有这些隐式强制转换是否是类型安全的)。换句话说,这是:List<String> list = new ArrayList<>();list.add("foo");System.out.println(list.get(0).length());只是一种更好的写作方式:List list = new ArrayList();list.add((String) "foo");System.out.println(((String) list.get(0)).length());虽然<String>看起来像是该类型的一部分,但它基本上只是向编译器发出大量指令的指令。具有不同类型参数的泛型类都具有相同的方法。这是您方法中的特定困难:您不能使BaseValidator<String>.getValidator()用checkIsNotEmpty方法返回内容(仅),而BaseValidator<Integer>.getValidator()用checkIsGreaterThan方法返回内容(仅)。好吧,这不是真的不能说你不能。尝试使用方法范围的类型变量(<C> C getValidator()),您可以编写:new BaseValidator<>("string").<StringValidator>getValidator().checkIsNotEmpty()(假设StringValidator上具有checkIsNotEmpty方法)但:让我们不要碎话:这很丑。比难看更糟糕的是,它不是类型安全的。您可以同样写:新的BaseValidator (“ string”)。getValidator()。checkIsGreaterThan(42)这是荒谬的,但编译器允许。问题是在调用站点选择了返回类型:您要么必须返回null(当您尝试调用以下方法时会得到NullPointerException);否则,将返回null。或返回一些非空值并冒ClassCastException的风险。两种方式:不好。但是,您可以做的是使通用验证器成为方法调用的参数。例如:interface Validator<T> { void validate(T b);}class BaseValidator<T> { BaseValidator<T> validate(Validator<T> v) { v.validate(this.value); }}并像这样调用,演示如何链接方法调用以应用多个验证:new BaseValidator<>("") .validate(s -> !s.isEmpty()) .validate(s -> s.matches("pattern")) ...new BaseValidator<>(123) .validate(v -> v >= 0) ...关于java - 编译时的泛型重载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54788992/
10-10 10:37