抽象类作为参数的通用方法

时间:2012-09-11 18:32:09

标签: java

您好我正在尝试创建一个泛型方法,该方法接受一个类型为抽象参数化类的参数。在方法内部,我想创建传递参数的实例,因为它是抽象类型的子类,因为我们无法实例化抽象类。

但是我遇到了一些问题。并且错误消息说无法将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);
        }
    }

2 个答案:

答案 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>>();

但请注意,FaRule的实际实体类不同。 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);