6

Consider that I have Algorithm enum as

public enum Algorithm {
  SHA1("sha1"),
  HMAC("hmac"),;

  Algorithm(final String algorithm) {
    this.algorithm = algorithm;
  }
  private final String algorithm;

  public String getAlgorithm() {
    return algorithm;
  }
}

and I have different algorithms as

public class Sha1 {
   public static String hash(final String text, final byte[] sb) {...}
}

and

public class Hmac {
   public static String hash(final String text, final byte[] sb) {...}
}

I want to return their instances when someone calls for example

Algorithm.SHA1.getInstance()

Question

  • How can I return the instance since my method is static? (It is static so that multiple threads can not play around with each other data)
2
  • To making it thread safe - what about using synchronization? Commented May 20, 2015 at 2:14
  • The same way you add a getAlgorithm() method you can also add a getInstance() method. You can implement that on the Enum or on the different ciphers. SHA1("sha1") { X getInstance() { return new Sha1(); }, Hmac("hmac") { X getInstance() { return new Hmac(); } (but that does not help you much with a static method - which is not a good idea in that case anyway). Commented May 20, 2015 at 4:14

1 Answer 1

6

You can't return an instance when your method is static, but you can make your enum implement an interface, and make an instance method that calls the static method perform the virtual dispatch for you:

public interface EncryptionAlgo {
    String hash(final String text, final byte[] sb);
}

public enum Algorithm implements EncryptionAlgo {
    SHA1("sha1") {
        public String hash(final String text, final byte[] sb) {
            return Sha1.hash(text, sb);
        }
    },
    HMAC("hmac") {
        public String hash(final String text, final byte[] sb) {
            return Hmac.hash(text, sb);
        }
    };

    Algorithm(final String algorithm) {
        this.algorithm = algorithm;
    }
    private final String algorithm;

    public String getAlgorithm() {
        return algorithm;
    }
}

Now you can call hash on the SHA1 or HMAC instance, like this:

Algorithm.HMAC.hash(someText, sb);

or pass around EncryptionAlgo instances, like this:

EncryptionAlgo algo = Algorithm.SHA1;
Sign up to request clarification or add additional context in comments.

3 Comments

Well, Algorithm could contain static instances of both Sha1 and Hmac and return one or the other, assuming that both those classes implement the EncryptionAlgo interface. But making Algorithm itself implement the interface seems better, since it avoids the need to call getInstance(). An enum instance is already a static singleton, so it's stilly to use one just to look up another static singleton.
Also, SHA1 and HMAC are hash functions, not encryption algorithms. The EncryptionAlgo interface would be better named something like HashFunction.
You don't actually need the interface. You can just have the method on the enum type directly.

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.