Reputation: 4677
I would like to make a set of utility classes that implement an interface. In order to do this, I will be using the singleton pattern. However, it would also be nice to be able to use those utility classes via static method calls. For example:
public interface IValidator<T> {
boolean isValid(T value);
}
public class StringValidator implements IValidator<String> {
public static final StringValidator instance = new StringValidator();
@Override
public boolean isValid(final String value) {
return true;
}
}
The above provides a singleton which enables me to call the utility methods using an interface, as follows:
// Use case #1
IValidator<String> validator1 = StringValidator.instance;
validator1.isValid("");
// Use case #2
StringValidator.instance.isValid("");
However, I would also like to be able to use StringValidator
in the following, more succinct way:
// Use case #3: How can I also allow this syntax?
StringValidator.isValid("");
Is there a way in Java to make all three of the above syntaxes work without renaming the method? The only idea I had was to add a varargs parameter to the static definition, as follows:
public class StringValidator implements IValidator<String> {
public static final StringValidator instance = new StringValidator();
@Override
public boolean isValid(final String value) {
return StringValidator.isValid(value);
}
public static boolean isValid(final String value, final Object... ignored) {
return true;
}
}
However, that fails with the message "Cannot make a static reference to the non-static method isValid(String) from the type StringValidator". Again, is there some way to make the compiler allow all three of my use-case syntaxes? Thanks.
Upvotes: 1
Views: 120
Reputation: 4677
I figured out a way. Change the code to the following:
public interface IValidator<T> {
boolean isValid(T value, Object... ignored);
}
public class StringValidator implements IValidator<String> {
public static final StringValidator instance = new StringValidator();
@Override
public boolean isValid(final String value, final Object... ignored) {
return isValid(value);
}
public static boolean isValid(final String value) {
return true;
}
}
Then all three of the use cases compile. Java will generate a warning for use case #2, but that doesn't bother me as I think the only sane use of the implementing class are cases #1 and #3.
Upvotes: -1
Reputation: 32980
If the interface is a functional interface you could drop the singleton
public class StringValidator {
public static boolean isValid(final String value) {
return ...;
}
}
and whenever you need a instance of Validator<String>
use a method handle to the static method:
IValidator<String> validator1 = StringValidator::isValid;
Upvotes: 3