帮助反射+构造函数

时间:2009-07-17 16:08:13

标签: java reflection constructor

我有代码我正在努力实例化依赖于传入的多项式的CRC算法,以及包含“crc8”或“crc16”或“crc32”的字符串s

CRC8CRC16CRC32都扩展了类CRC并实现了接口HashAlgorithm。他们每个人都有一个构造函数CRCx(int polynomial)

我的问题是,我在所有3个getConstructor()行上都出现了这个错误:

Type mismatch: 
  cannot convert from Constructor<HashFactory.CRC16> 
  to Constructor<HashFactory.CRC>

任何人都可以帮忙解释原因,并帮我解决这个问题吗?

    int polynomial; // assign from somewhere
    Constructor<CRC> crc = null;
    if ("crc8".equals(s))
    {
        crc = CRC8.class.getConstructor(Integer.TYPE);
    }
    if ("crc16".equals(s))
    {
        crc = CRC16.class.getConstructor(Integer.TYPE);
    }
    if ("crc32".equals(s))
    {
        crc = CRC32.class.getConstructor(Integer.TYPE);
    }
    if (crc != null)
    {
        CRC crcInstance = crc.newInstance(polynomial);
        return (HashAlgorithm) crcInstance;
    }

4 个答案:

答案 0 :(得分:5)

尝试

    int polynomial; // assign from somewhere
    if ("crc8".equals(s)) {
            return new CRC8(polynomial);
    } else
    if ("crc16".equals(s)) {
            return new CRC16(polynomial);
    } else
    if ("crc32".equals(s)) {
            return new CRC32(polynomial);
    }

或者

package tests;
import java.lang.reflect.Constructor;
public class Construct {
    static interface CRC { }
    static class CRC8 implements CRC {
        public CRC8(int p) { }
    }
    static class CRC16 implements CRC {
        public CRC16(int p) { }
    }
    static class CRC32 implements CRC {
        public CRC32(int p) { }
    }
    public static CRC getAlg(String s, int polynomial) {
        try {
            Class<?> clazz = Class.forName("tests.Construct$" + s.toUpperCase());
            Constructor<?> c = clazz.getConstructor(Integer.TYPE);
            return CRC.class.cast(c.newInstance(polynomial));
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new AssertionError("Unknown algorithm: " +s);
    }
    public static void main(String[] args) throws Exception {
        System.out.println(getAlg("crc8", 0));
        System.out.println(getAlg("crc16", 0));
        System.out.println(getAlg("crc32", 0));
        System.out.println(getAlg("crc48", 0));
    }
}

“工厂”模式:

    public static HashAlgorithm getHashAlgorithm(String s, int polynomial) {
        if ("crc8".equals(s)) {
            return new CRC8(polynomial);
        } else
        if ("crc16".equals(s)) {
            return new CRC16(polynomial);
        } else
        if ("crc32".equals(s)) {
            return new CRC32(polynomial);
        }
        throw new AssertionError("Unknown algorithm: " +s);
    }

可以通过其他几种方式完成(例如,算法的HashMap到可复制的CRC类等)。

答案 1 :(得分:4)

尝试像这样声明crc变量:

Constructor<? extends CRC> crc = null;

答案 2 :(得分:4)

由于泛型的奇迹,Constructor<HashFactory.CRC16>Constructor<HashFactory.CRC>的类型不兼容。您需要为变量选择更通用的内容,例如:

Constructor<? extends CRC> crc = null;

答案 3 :(得分:1)

其他人已经为您的问题提供了解决方案,但我的建议是不要在您不需要的地方使用Java反射。使用反射的解决方案通常更慢,代码更复杂,并且通常需要考虑更多“动态类型”失败案例。

在您的特定示例中,“对象工厂”模式比使用反射调用构造函数更好。