2009-07-17 5 views
1

전달 된 다항식에 의존하는 CRC 알고리즘과 "crc8"또는 "crc16"또는 "crc32"가 포함 된 s 문자열을 인스턴스화하는 코드가 있습니다.reflection + 생성자에 대한 도움말

클래스 CRC8, CRC16CRC32 모든 클래스 CRC를 확장하고 인터페이스 HashAlgorithm를 구현합니다. 각각은 생성자 CRCx(int polynomial)을 가지고 있습니다.

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

하는 사람이 이유를 설명하고 나에게이 문제를 해결할 수 있도록 도와 줄 수 :

내 문제는 내가 getConstructor 메소드() 라인의 3에이 오류가있다?

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; 
    } 
+2

리플렉션을 사용하는 특별한 이유가 있습니까? –

+0

음, 어, 나는 이유가 있었는데, 지금 생각할 수 없다. "kd304"는 좋은 지적입니다. –

+0

팩토리 패턴을 사용하고 새로 초기화 된 HashAlgorithm을 반환하는 것은 어떻습니까? 그런 다음 컴파일 시간을 확인하고 약간 더 빠르게 실행해야합니다. –

답변

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

를이 여러 다른 방법으로 수행 할 수 있습니다 (예 : CRCs의 복제 가능한 클래스에 대한 알고리즘의 HashMap)

+0

ㅎ. 내 의견은 "이런! 잊어 버린 것을 믿을 수 없어"와 "와우"입니다. –

+0

@ Jason S : 예. 자바를 배우고 있습니까?당신은 Java로부터 많은 rep을 가지고있는 것 같습니다 - 또는 그것은 단지 많은 질문들로부터입니까? – akarnokd

+0

나는 75 %의 질문과 25 %의 답변을 말할 것입니다. 나는 지난 1 년 정도 자바를 계속 배우고 있습니다. 저는 소프트웨어 엔지니어가 아닌 전기 엔지니어로서 데이터 처리/소프트웨어 작업을 산발적으로 수행하므로 자바를 사용하여 신속하게 뭔가를 배우고 나서 배운 것들의 절반을 잊을 때가되었습니다. ... :/ –

4

이 같은 crc 변수를 선언하십시오 :

Constructor<? extends CRC> crc = null; 
4

감사 제네릭의 경이로움에, Constructor<HashFactory.CRC16>Constructor<HashFactory.CRC> 호환 입력되지 않습니다. 이처럼, 당신의 변수에 대해 더 일반적인 무언가를 선택해야합니다

Constructor<? extends CRC> crc = null; 
1

다른 사람들이 당신의 문제에 대한 해결책을 제시해 왔지만, 다른 사람들은 당신이 필요로하지 않는 곳에서 Java reflection을 사용하지 않는 것이 좋습니다. 리플렉션을 사용하는 솔루션은 일반적으로 더 느리고 코드는 더 복잡하며 일반적으로 더 많은 "동적 타이핑"실패 사례가 고려됩니다.

"object factory"패턴은 리플렉션을 사용하여 생성자를 호출하는 것보다 나은 해결책입니다.