我有一个方法,通用类型T
作为参数
private static <T> void doValidation(T[] pArray, int size, String firstName, String secondName) {
...
for (int i = 0; i < size; i++) {
...
validate(pArray[i]);
}
}
然后我根据具体类型给出了不同的方法,例如A
,B
等。
private static void validate(A a) {
}
private static void validate(B b) {
}
我希望它在运行时解析类型并根据类型调用相应的方法,是否可能?
目前我
no suitable method found for validate(T)
method ValidateDataStructure.validate(A) is not applicable
(argument mismatch; T cannot be converted to A)
method ValidateDataStructure.validate(B) is not applicable
(argument mismatch; T cannot be converted to B)
where T is a type-variable:
T extends Object declared in method <T>doValidation(T[],int,String,String)
----
(Alt-Enter shows hints)
它希望我当然可以演绎这个论点。
我正在尝试做一个Assimp的端口,我的意图是尽可能接近C结构。 This是我正在尝试移植的功能..
答案 0 :(得分:1)
如果您要验证无法扩展的类型(例如Integer
,String
),
您可以实现自己的动态调度。例如,您可以创建这样的验证器映射(Java-8):
private static final Map<Class<?>, Consumer<?>> validators = new HashMap<>();
static {
validators.put(A.class, (A a) -> validate(a));
validators.put(B.class, (B b) -> validate(b));
...
}
并编写一个选择器方法:
static <A> Consumer<A> getValidator(Class<A> clazz) {
// do nothing for unknown type
return (Consumer<A>)validators.getOrDefault(clazz, () -> {});
}
最后你可以像这样使用它:
getValidator(value.getClass()).validate(value);
答案 1 :(得分:0)
根据您的确切需求,您的问题并不完全清楚,您有一些选择。
您可能实际上并不需要doValidation
方法根据T
采取不同的行为,而是根据运行时类型使用validate
方法表现不同它的论点。这是一个有点不同的问题,但它很容易解决:最好的选择可能是让它委托给一个可覆盖的方法,如:
private static <T extends Validatable> void validate(T arg)
{
arg.validate();
}
(当然,您需要定义适当的Validatable
接口,并且doValidation方法中的T
类型参数也需要声明为T extends Validatable
)。
但是,上述选项要求您可以修改类A
和B
(使它们实现Validatable
)。从设计的角度来看,但没有这个限制,另一个选择并不是那么干净,而是通过引入validate
方法来确定类型并相应地分配给不同的方法,如下所示:Object
:
private static void validate(Object arg)
{
if (arg instanceof A) {
validate((A) arg);
}
else if (arg instanceof B) {
validate((B) arg);
}
else {
throw new RuntimeException("Don't know how to validate object of class " + arg.getClass.getName());
}
}