您好我正在尝试创建一个泛型方法,该方法接受一个类型为抽象参数化类的参数。在方法内部,我想创建传递参数的实例,因为它是抽象类型的子类,因为我们无法实例化抽象类。
但是我遇到了一些问题。并且错误消息说无法将RuleType解析为一种不足为奇的类型,但我不知道如何实现这一点。 我目前的代码如下。
private <F extends AbstractRule<T>, T> void applyRyle(F cRule,ArrayList<T> aFeatures)
{
Class RuleType = cRule.getClass();
// if the parameter passed is a subclass of AbstractRule create some objects
if(!RuleType.getSuperclass().getName().equals("AbstractRule"))
{
ArrayList<RuleType<T>> aRules = new ArrayList<RuleType<T>>();
for(int i = 0; i < 10; i++)
{
RuleType<T> aRule= new RuleType<T(pattern.getMatrices().size(), 2,aFeatures);
aRule.initialise(aRule.getMaxLocalLevel());
aRules.add(aRule);
}
}
答案 0 :(得分:2)
其中一些可以通过使用反射来完成:
private <F extends AbstractRule<T>, T> void applyRyle(F cRule, ArrayList<T> aFeatures)
{
Class<? extends F> ruleType = cRule.getClass();
// if the parameter passed is a subclass of AbstractRule create some objects
if(! ruleType.getSuperclass().getName().equals("AbstractRule"))
{
ArrayList<? extends F> aRules = new ArrayList<? extends F>();
for(int i = 0; i < 10; i++)
{
F aRule =
ruleType
.getConstructor(int.class, int.class, ArrayList.class)
.newInstance(pattern.getMatrices().size(), 2, aFeatures);
aRule.initialise(aRule.getMaxLocalLevel());
aRules.add(aRule);
}
}
虽然这可能不是实现你真正想要的最佳方式。
答案 1 :(得分:2)
首先,您不需要以下行,因为您的通用声明保证cRule将是AbstractRule
的实例。
if (!RuleType.getSuperclass().getName().equals("AbstractRule"))
在运行时检查上述内容的正常和更好的方法是使用instanceof
if (!cRule instanceof AbstractRule)
至于您的ArrayList
声明,您可以执行以下操作:
ArrayList<F<T>> aRules = new ArrayList<F<T>>();
但请注意,F
与aRule
的实际实体类不同。 F
将是调用该方法的类型。也就是说,F
将比aRule
的类更宽(它可能包括F
的其他子类,它们不是aRule
类的子类。
但是,您无法直接创建F
的新实例。你需要有一些代理方法来为你做。也就是说,你不能写new F()
。我们可以做什么(因为我们已经有F
的具体实例)是向AbstractRule
添加一个抽象方法,可以创建自己的新实例,例如。
public interface AbstractRule<T extends AbstractRule> {
T newRule(some parameters you need in the constructor);
}
现在我们可以写:
F newRule = aRule.newRule(pattern.getMatrices().size(), 2,aFeatures);