1

I have code I'm working on to instantiate a CRC algorithm dependent on a polynomial passed in, and a string s that contains "crc8" or "crc16" or "crc32".

The classes CRC8, CRC16, and CRC32 all extend a class CRC and implement an interface HashAlgorithm. Each of them has a constructor CRCx(int polynomial).

My problem is, I get this error on all 3 of the getConstructor() lines:

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

Can anyone help explain why and help me fix this?

    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;
    }
8
  • 2
    Is there any particular reason you are using reflection? Commented Jul 17, 2009 at 16:30
  • Um, er, I had a reason, can't think of it now. "kd304" has a good point. Commented Jul 17, 2009 at 17:27
  • Why not use the factory pattern and return a newly instiantiated HashAlgorithm? You'll then get compile time checking and it should run slightly faster. Commented Jul 17, 2009 at 17:27
  • I think it was because I had a related example where I couldn't cleanly separate my code in a way that would work w/ explicit creation of objects... but that doesn't make sense.... Commented Jul 17, 2009 at 17:28
  • @Steve Kuo: factory pattern in what sense? Do you mean each HashAlgorithm having a separate factory that instantiates the desired object on demand? Commented Jul 17, 2009 at 17:30

4 Answers 4

5

Try

    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);
    }

Or

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));
    }
}

"Factory" pattern:

    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);
    }

It can be done several other ways (e.g HashMap of algorithms to duplicatable classes of CRCs, etc.)

Sign up to request clarification or add additional context in comments.

4 Comments

heh. My comments are "duh! can't believe i forgot that" and "wow", respectively.
@Jason S: Yeah. Are you learning Java now? You seem to have a ton of rep from Java - or it is only from the ton of questions?
I would say 75% questions, 25% answers... I've been learning Java off and on for the past year or so. I'm an electrical engineer, not a software engineer, with data processing/software tasks sporadically, so I get into these bursts of needing to use Java and learn something quickly, then time in-between to forget half of what I've learned... :/
I suspected that. Yet another good example to Rep is not about how good you are in the subject. Still it makes this impression for everyone I guess. Btw, are you waiting for more answer?
4

Try declaring the crc variable like this:

Constructor<? extends CRC> crc = null;

Comments

4

Thanks to the wonders of generics, Constructor<HashFactory.CRC16> is not type compatible with Constructor<HashFactory.CRC>. You need to pick something more general for your variable, like this:

Constructor<? extends CRC> crc = null;

Comments

1

Others have offered solutions to your problem, but my advice is to not use Java reflection where you don't need to. A solution that uses reflection is typically more slower, the code is more complex, and there typically are more "dynamic typing" failure cases to consider.

In your particular example, the "object factory" pattern is a better solution than using reflection to invoke constructors.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.