I read "Effective Java" by Joshua Bloch and removed the 'Constant Interface anti-pattern' from our application. The trick is to use Non-instantiable util class whose constructor is private, and define all the constants as 'public static final'
I have to extend the this constant util class. I can only do this when I change the constructor to protected.
Could somebody suggest a better way.
public class Constants {
private Constants () {} // Prevent instantiation
public static final String MyString = "MyString";
}
public class MyConstants extends Constants {
private MyConstants () {} // Compiler error : Implicit super constructor Constants() is not visible.
public static final String MySecondString = "MySecondString";
}
You are not typically supposed to extend these constant classes. Could you provide us with a more concrete example of what you're trying to do?
Typically you'd want to group constants together when they are related, e.g., maths constants or configuration parameter names for a particular functional component.
If the constants are really related, is there anyway you could just add them to the original class? Alternatively, is there any reason you can't create a separate class for your constants?
I usually do the following:
public abstract class Constants {
// ...constants...
public Constants () {
throw new UnsupportedOperationException(); // prevent instantiation
}
}
This way the class can be extended to create a derived utility class, but any (misguided) attempt to instantiate it will fail. I wish java.util.Collections was defined that way, so one wouldn't have to define a Collections2 (or similar) for additional utility methods.
BTW, given an abstract class, "protected" and "public" effectively mean the same for constructors. There's practically no benefit in just making a constructor protected, as anyone can still easily create an instance of the class despite the "protection":
public class Base {
protected Base() { }
}
// Somewhere else:
Base b = new Base() { }; // anonymous subclass
I don't see anything wrong with changing the constructor to protected.
I also don't see anything wrong with using interfaces to hold constants.
If the classes are in the same package and you want to forbid inheritance for non-package classes, consider using default access:
public class Constants {
Constants () {} // Prevent instantiation
public static final String MyString = "MyString";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With