我有代码我正在努力实例化依赖于传入的多项式的CRC算法,以及包含“crc8”或“crc16”或“crc32”的字符串s
。
类CRC8
,CRC16
和CRC32
都扩展了类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;
}
答案 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反射。使用反射的解决方案通常更慢,代码更复杂,并且通常需要考虑更多“动态类型”失败案例。
在您的特定示例中,“对象工厂”模式比使用反射调用构造函数更好。