Are enums less maintainable than public static final constants? - java

I was recently discussing enums vs public static final constants with a friend. I told him that public static final constants are more maintainable than enums, sometimes faster (android developer docs confirm this), and more convenient as well. I also said that you lose functionality when using enums as well:
You cannot extend an enum.
You cannot instantiate an enum.
He then said you shouldn't be using an enum if you need to instantiate or extend an enum. I then replied that's why we should just use constants because it is more maintainable; What if mid project we need to instantiate an enum or extend it? Then we would have to change everything.
An example demonstrating enums vs constants I made to illustrate my point:
public enum WeekDay {
/*
* We will start at 1 for demonstration
*/
SUNDAY("Sunday", 1), MONDAY("Monday", 2), TUESDAY("Tuesday", 3), WEDNESDAY(
"Wednesday", 4), THURSDAY("Thursday", 5), FRIDAY("Friday", 6), SATURDAY(
"Saturday", 7);
/*
* Notice we cannot do this...This is where enums fail.
*/
// LUNES("lunes",1), MARTES("martes",2);
private String dayName;
private int dayIndex;
private WeekDay(String dayName, int dayIndex) {
this.dayName = dayName;
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
}
What if we need Spanish week days as well? The enum falls short because you cannot extend it (you would have to do some copy and paste action).
Contrast the enum with this:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
abstract static class Constants {
}
public static void main(String[] args) {
WeekDayClass init = new WeekDayClass(10, "I can init new days here");
}
}
And then I can extend it and make AmericanWeekDays:
public class AmericanWeekDay extends WeekDayClass {
public AmericanWeekDay(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class AmericanConstants extends Constants {
public static final WeekDayClass SUNDAY = new WeekDayClass(1, "Sunday");
public static final WeekDayClass MONDAY = new WeekDayClass(2, "Monday");
/*
* And so on...
*/
}
}
Or Spanish Week Days:
public class SpanishWeekDays extends WeekDayClass {
public SpanishWeekDays(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class SpanishConstants extends Constants {
public static final SpanishWeekDays LUNES = new SpanishWeekDays(2, "lunes");
/*
* And so on...
*/
}
}
Also to go even further:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
static class AmericanConstants {
/*
* Insert Constants Here
*/
}
static class SpanishConstants {
/*
* Insert Constants Here
*/
}
}
I understand with an enum you could perhaps make a workaround using data structures (Lists) so you accommodate this shortcoming but why bother? With using public static constants I gain inheritance from the base class, cleaner code, possibly shorter code, and easier maintainability.
I also read that you can use enum's to better design "input parameters" but you could also do the same with the public static final constants as shown above.
Enums have the advantage of being able to be used in switch statements and have the inherited enum methods like values(). These methods can also be replicated if needed in "public static final constant" classes. Aside from the switch I don't see any enum advantages.
In conclusion, is an enum really better than public static final constants? If so, where did I go wrong? Is their something I am missing?
EDIT:
You cannot use generics in enums as well.

Enums get you a lot more than you seem to give them credit for, and while sometimes constants are required, this case is probably a win for enums.
First of all, there is no real difference between an "English weekday" and a "Spanish weekday", they represent the same values. Therefore, the best solution would be to do the conversion to string independently of what the values actually are through some kind of localization method. The values don't change with the language, their representation does.
This is entirely doable quickly and easily with enums. Just write it like this (a little pseudocode-y):
public enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY,
...;
public String toLocalizedString(Language l) {
// interact with localization files
}
}
You are conflating the ideas of external representation and internal representation. Your data should be as homogenous as possible because there is only ever going to be one Monday. It might be called different things, but it's still the same value.
Enums also get you a lot of niceness for free, though, which makes your code much clearer and more maintainable in the long run. Type checking, == comparison, and usability in switch are a few, with no boilerplate to speak of.

I think you're taking the usage of enums way to far and then come to a conclusion that they are not useful.
Enums are simply telling you that there's a limited and predefined number of options to choose from. Nothing more than that. For example, when you see a parameter that is an enum (let's say State) and it has 3 values (Pending, InProgress, Closed), you know that a state of some object can have one of those and only one of those values.
Enums provide an easy way of validating that a proper value is used as you cannot easily select a value that is not proper when coding. They are also a way of documenting as you can easily see what options are available.

Enumerations wouldn't exist if they weren't useful - the same can be said of constants. Just like a screwdriver can remove a screw while a hammer can remove a nail - different tools in your programmer "toolbox" can be used for unique and important purposes. I suggest reading more about enumerations and constants and I think you will find why they exist and when to use them.

Related

Can adding conditional diagnostics in Java be zero cost when they are off?

This is really a question about Java, not c++.
The idea is you'd like to be able to add in-line diagnostics that you could turn on and off by setting a flag. And you'd like the cost to be low and near or at zero when the flag is turned off.
Years ago I implemented a class I called "Debugger" in C++ that did this. The design uses enums for the flag names so you can have code that's readable and efficient and type-safe. The usage looks like this.
enum DebugBits {
testCondition1,
testCondition2,
testCondition3
nTestConditions
}`
Debugger testDebug("testDebug", nTestConditions,
"condition1",
"condition2",
"condition3");
Critical::doStuff()
{
...
if (testDebug.on(testCondition2))
doSomethingSpecial();
...
}
This was easily implemented with bits indexed with the enum values and inline methods. It works well in a large real-time system and has very near zero cost when the debugging is turned off. Its a valuable tool.
Anyway, back to the question. Today I was looking at doing the same thing in Java, for personal reasons, but given that you can't subclass enums, and yet it would be good to use them, its not so easy to keep the declaration clear and the usage in the code brief.
So here's an implementation that works, and is somewhat efficient. The questions are,
Can the implementation be more efficient?
At the same time can the usage in the code be kept clear?
I suspect there are better Java coders out there that may have better ideas about how to do this. Add a package at the top and this should compile and run. There is another class at the bottom to demonstrate the usage. Note that there's lots more that should be in this, but this is the core part the is interesting. Well... to me.
import java.util.BitSet;
import java.util.EnumSet;
import java.util.Vector;
public class Debugger {
private final EnumSet mEnumSet;
private final BitSet mBits;
private final Vector<String> mNames;
public Debugger(EnumSet es) {
mEnumSet = es;
mBits = new BitSet(es.size());
mNames = new Vector<>();
for (Object i : mEnumSet)
mNames.add(i.toString());
}
public void set(int bit) {
mBits.set(bit);
}
public void set(String bitName) {
int bit = mNames.indexOf(bitName);
if (bit >= 0)
mBits.set(bit);
}
public boolean on(int bit) {
return mBits.get(bit);
}
public boolean on(Object arg) {
if (arg.getClass() == Enum.class) {
int bit = ((Enum)arg).ordinal();
return mBits.get(bit);
}
return false;
}
public boolean on(String bitName) {
int bit = mNames.indexOf(bitName);
return bit >= 0 && mBits.get(bit);
}
}
class SampleUsage {
static class Debug extends Debugger {
enum Bits {
zero, one, two, three;
public static final EnumSet<Bits> bits = EnumSet.allOf(Bits.class);
}
public Debug() {
super(Bits.bits);
}
}
public static final Debug debug = new Debug();
public SampleUsage() {}
void doStuff() {
if (debug.on(Debug.Bits.three))
showDebugInfo();
if (debug.on("three"))
showDebugInfo();
}
private void showDebugInfo() {}
}
I think you’ve missed the point of EnumSet<>. The EnumSet<> is your type-safe set of highly efficient debug flags.
enum Debug {
FLAG0, FLAG1, FLAG2;
}
EnumSet<Debug> debug = EnumSet.noneOf(Debug.class);
debug.add(Debug.FLAG0);
if (debug.contains(Debug.FLAG0)) {
showDebugInfo0(); // Will be executed.
}
if (debug.contains(Debug.FLAG1)) {
showDebugInfo1(); // Will not be executed because FLAG1 was not added to the EnumSet.
}
There is no need to translate the enum values into ordinals, and add that ordinal to a BitSet. EnumSet<> is already implemented using something like a BitSet (except the EnumSet<> is of a fixed size, based on the number of identifiers in the Enum, so cannot be extended to an arbitrary length).
If you want to test if a flag is set by name, you can use the Enum.valueOf() to convert the name into the correct Enum, and test if the EnumSet<> contains that.
if (debug.contains(Enum.valueOf(Debug.class, "FLAG2")) {
showDebugInfo2(); // Also not executed, because FLAG2 was not added to the EnumSet.
}
Again, no need for a Vector<String> that contains all of the Enum names, which you must find the .indexOf(). The Enum comes with that method built-in. Vector<> was not an efficient choice to use anyway, since Vector<> operations are automatically synchronized, so are slightly slower than an equivalent ArrayList<>.
Note: Minor difference: .indexOf() returns -1 when not found; Enum.valueOf() will raise an IllegalArgumentException if you give it an unknown identifier name.
Assuming you want .on(), not .contains(), and you want simpler test flag by name usage in your code, we’ll need to wrap the EnumSet<> in another class. This Debug class might look like:
class Debug<T extends Enum<T>> {
private final Class<T> enum_class;
private final EnumSet<T> flags;
public Debug(Class<T> enum_class) {
this.enum_class = enum_class;
flags = EnumSet.noneOf(enum_class);
}
public void set(T flag) {
flags.add(flag);
}
public boolean on(T flag) {
returns flags.contains(flag);
}
public void set(String flag_name) {
flags.add(Enum.valueOf(enum_class, flag_name));
}
public boolean on(String flag_name) {
return flags.contains(Enum.valueOf(enum_class, flag_name));
}
}
So with minor mods to your implementation, it shows brevity and clarity and uses fewer resources. The Enum.valueOf() I missed entirely. The string conversion is a goal I did not describe, but is useful when trying to set bits through a subsystem that is unaware of the class containing the enums, but the user knows the names. I got parts of it right, but you got me out of the weeds. Thanks much.
Oh... and I changed the name.
import java.util.EnumSet;
class Diagnostic<T extends Enum<T>> {
private final Class<T> enum_class;
private final EnumSet<T> flags;
public Diagnostic(Class<T> enum_class) {
this.enum_class = enum_class;
this.flags = EnumSet.noneOf(enum_class);
}
public void set(T flag) {
flags.add(flag);
}
public boolean on(T flag) {
return flags.contains(flag);
}
public void set(String flag_name) {
try {
flags.add(Enum.valueOf(enumClass, flag_name));
}
catch (Exception e) {}
}
public boolean on(String flag_name) {
try {
return flags.contains(Enum.valueOf(enumClass, flag_name));
}
catch (Exception e) {
return false;
}
}
}
class SampleUsage {
enum DiagBits {
zero, one, two, three;
}
public static final Diagnostic<DiagBits> diag = new Diagnostic<>(DiagBits.class);
public SampleUsage() {}
void doStuff() {
if (diag.on(DiagBits.three))
showDebugInfo();
if (diag.on("three"))
showDebugInfo();
}
private void showDebugInfo() {}
}

Enums as replacement of Constants in Java

I heard now a day that We should use Enums instead of Constants .
Is it possible in all cases ? Whether enums are replacement of Constants ?
In Below Example I have Constants defined in Constants file and ConstantsTest uses them
public final class Constants {
private Constants(){
}
public static final String ACCOUNT="Account";
public static final String EVENT_ITEM ="EventItem";
public static final int MULTIPLIER_ONE = 1;
public static final int MULTIPLIER_NEGATIVE_ONE = -1;
public static final String BALANCE_AFTER_MODIFICATION = "BalanceAfterModification";
public static final String COMMA = ",";
public static final String DOTPSV =".psv";
public static final String NEW_LINE = "\n";
}
// Test Class
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ConstantsTest {
private static File rootDir = new File(".");
public static void main(String[] args) throws IOException {
Map<String,Integer> accountBalance = new HashMap<String, Integer>();
accountBalance.put("123",55000);
accountBalance.put("223",15000);
writeToFile(Constants.ACCOUNT, accountBalance, true, 2000);
// do operation
}
/**
*
* #param fileType
* #param inputData
* #param add if true add balance else substract the balance
* #return
* #throws IOException
*/
private static File writeToFile(String fileType , Map<String,Integer>accountBalance ,boolean add, int amount) throws IOException{
File file = null;
FileWriter fw = null;
try{
if(Constants.ACCOUNT.equals(fileType)){
file = new File(rootDir,Constants.ACCOUNT+Constants.DOTPSV);//creating a fileName using constants
fw = new FileWriter(file);
fw.write(Constants.ACCOUNT+Constants.COMMA+Constants.BALANCE_AFTER_MODIFICATION);//Writing Header in file using constant values
updateBalance(accountBalance, add, amount);
for(String key:accountBalance.keySet()){
fw.write(Constants.NEW_LINE);
fw.write(key+Constants.COMMA+accountBalance.get(key));
}
}
else if(Constants.EVENT_ITEM.equals(fileType))
{
// write to EventItem.psv
}
} finally{
if (null!=fw){
fw.close();
}
}
System.out.println("File created successfully");
return file;
}
private static void updateBalance(Map<String, Integer> accountBalance,
boolean add, int amount) {
for(String key:accountBalance.keySet()){
int currentBal = accountBalance.get(key);
if(add){
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_ONE); // do lot of calculations
}else{
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_NEGATIVE_ONE);// do a lot of calculations
}
}
}
}
Please suggest in my sample example enums would be better or my current approach of using constants is good enough ?
In your particular case the using enums is classic solution.
First, let's re-write your Constants as an enum:
public enum Constants {
ACCOUNT,
EVENT_ITEM,
;
}
public enum Operation {
MULTIPLIER_ONE {
public int action(int value) {
return value;
}
},
MULTIPLIER_NEGATIVE_ONE {
public int action(int value) {
return value * (-1);
}
},
;
private Operation(int coef) {
this.coef = coef;
}
public abstract int action(int value);
}
Now instead of writing:
if(Constants.ACCOUNT.equals(fileType)){
} else if(....)
you can either use switch/case or even better define: define method (let's call it action() into the enum and call it from your code. See example in Operation enum above. In this case you code becomes trivial: no more if/else or switch statements. Everything is simple. Validation is done at compile time: you defined abstract method in enum you cannot add yet another element to enum without implementing this method for it. This does not happen when using if/else structures maintenance of which is a programmer's responsibility.
I know only one limitation of enums: using string contstants in annotations. There are a lot of annotations with string attributes. For example XmlElement(name="foo"). Even if you define enum
enum FooBar {
foo, bar
}
you cannot use it in annotations:
#XmlElement(name=FooBar.foo) // is wrong because String type is required
#XmlElement(name=FooBar.foo.name()) // is wrong because annotations do not support method invocation
In all other cases I prefer enum.
You should use enums this code
enum Constants {
ACCOUNT,
EVENT_ITEM ,
COMMA ,
DOTPSV ,
BALANCE_AFTER_MODIFICATION ;
#Override
public String toString() {
switch(this) {
case ACCOUNT: return "Account";
case EVENT_ITEM : return "EventItem";
case COMMA : return ",";
case DOTPSV : return ".psv";
case BALANCE_AFTER_MODIFICATION : return "BalanceAfterModification";
default: throw new IllegalArgumentException();
}
}
}
Only we can use Enums for the constant values which are in the single group.
Let us suppose: Weeks, Months, Colours, Gender, Process states
It is not the good idea to use single enum for storing all constants. Instead we can use one enum for each group of constants.
Let us suppose you have maintaining some colour codes then better to have Colour enum instead of saving as constants.
An Enum doesn't define a contract for the class using it, an interface does. A class which uses an Enum isn't of the type an Enum. A class which implements an Interface is effectively of the same type as the interface (the Interface is the parent.. and the reference could be changed). Considering these design issues. Tell me, is your approach correct?
You got enum wrong, it's not like you should create an enum instead of constant: an enum is a group of constants that are related, for example:
enum Days {
SUNDAY, MONDAY, TUESDAY, ...
}
From the docs:
An enum type is a special data type that enables for a variable to be
a set of predefined constants.
Constants will be better for the example provided. Interface variables are public static final by default.
public static final String ACCOUNT="Account";
See Why are interface variables static and final by default?

Extending enum fields Java

I know that it isn't possible to extend enum in Java, but I am trying to find an elegant solution for the below
I am trying to model enums (or classes) which will contain http end points of various web services across regions, say I have service A and B, each will have 4 region specific end points in US, EU, JP or CN. (This is basically for some seperate debug code that I am writing, in production the end points will be picked from configuration)
I was hoping to do something like this (not compliant java code).
public enum IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public enum ServiceAEndPoint extends IEndPoint {
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
}
I could do this using interfaces where I have a method for each region, but in my opinion the enum way is more expressive, is there any better way I could model this ? What I am looking for is if there is any better way to model the inheritence relation and also having the expressive power of enumerations.
ServiceAEndPoint.NA_END_POINT
vs
serviceAEndPoint.getNAEndPoint()
I'm assuming that you will also want a ServiceBEndPoint enum (and similar). In which case I don't think your model really makes that much sense.
IEndPoint is really an enumeration of the kind of environments/regions where a service might be running. It is not an enumeration of the services themselves. Each individual service (A, B or whatever) will have different addresses for each of the regions.
Therefore I would stick with just the IEndPoint enum, and then in some service-specific code have a lookup map that will give you the address for a given end-point. Something like this:
public enum IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public class ServiceABroker {
private static final Map<IEndPoint, String> addressesByEndPoint;
static {
addressesByEndPoint = new EnumMap<>();
addressesByEndPoint.put(NA_END_POINT, "http://A.com/");
addressesByEndPoint.put(EU_END_POINT, "http://A-eu.com/");
addressesByEndPoint.put(JP_END_POINT, "http://A-jp.com/");
addressesByEndPoint.put(CN_END_POINT, "http://A-cn.com/");
}
public String getAddressForEndPoint(IEndPoint ep) {
return addressesByEndPoint.get(ep);
}
}
If these are static final constants, then just put them in an interface. Name the interface something like IServiceAEndPointKeys, where the keys part is a convention.
Here's where I consider enums to be more appropriate and useful:
Example 1: File type. An enum containing jpg, pdf etc.
Example 2: Column definitions. If I have a table with 3 columns, I would write an enum declaring ID, Name, Description (for example), each one having parameters like column header name, column width and column ID.
Im not sure I understand you question, but you can add methods to an enum for example you could do something like the following:
public enum ServiceAEndPoint{
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
private final String url;
private EndPoint(String url){
this.url=url;
}
public String getURL(){
return url;
}
}
Enums cannot be extended in such a manner, mostly because enums cannot be sub-classed or the constraints they must adhere to will not be possible to impose.
Instead leverage interfaces, like so
public interface IEndPoint;
public enum DefaultEndPoints implements IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public enum DefaultServiceEndPoints implements IEndPoint {
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
}
public void doSomething(IEndPoint endpoint) {
...
}
The reason why one can't subclass in the manner you wish is related to the contract that enums will be both equal via .equals(object) and via ==. If you could subclass, would this make sense?
if ( (DefaultEndPoints)JP_END_POINT == (DefaultServiceEndPoints)JP_END_POINT) {
}
if you say "yes" then I would expect to be able to do this
DefaultEndPoint someEndpoint = DefaultServiceEndPoints.JP_END_POINT;
which would leave a door open for error, as there is no guarantee that a enum entry in one enum declaration is in the other enum declaration.
Could it be different? Perhaps, but it isn't, and changing it would definately introduce a lot of complications that would have to be thoroughly thought out (or it would open avenues to work around Java's strong static-type checking).
You may want to consider something like this:
public abstract class EndpointFactory {
public abstract String getNAEndPoint();
public abstract String getEUEndPoint();
}
public class ServiceAEndpointFactory extends EndpointFactory {
public static final String NA_END_POINT = "http://A.com/";
public static final String EU_END_POINT = "http://A-eu.com/";
public String getNAEndPoint() {
return ServiceAEndpointFactory.NA_END_POINT;
}
public String getEUEndPoint() {
return ServiceAEndpointFactory.EU_END_POINT;
}
}
public class ServiceBEndpointFactory extends EndpointFactory {
public static final String NA_END_POINT = "http://B.com/";
public static final String EU_END_POINT = "http://B-eu.com/";
public String getNAEndPoint() {
return ServiceAEndpointFactory.NA_END_POINT;
}
public String getEUEndPoint() {
return ServiceAEndpointFactory.EU_END_POINT;
}
}
Then you can refer to your strings directly like this:
ServiceAEndpointFactory.NA_END_POINT;
Or, you can use the base object if the type of service is not known until execution:
EndpointFactory ef1 = new ServiceAEndpointFactory();
String ep = ef1.getNAEndPoint();
The drawback of this is the redefinition of the get*Endpoint() functions in each sub-class. You could eliminate that by moving the static final variables to be not static in the base class and putting the getter/setter in the base class only one time. However, the drawback of that is you are not able to reference the values without instantiating an object (which essentially emulates what I find valuable with ENUMs).
How does a pattern like this appeal to you? I let the enum implement an interface and implement the interface in a Debug set and a Release set. The release set can then derive the property name from the enum name - which is neat.
public interface HasURL {
public String getURL();
}
public enum DebugEndPoints implements HasURL {
NA,
EU,
JP,
CN;
#Override
public String getURL() {
// Force debug to go to the same one always.
return "http://Debug.com/";
}
}
public enum NormalEndPoints implements HasURL {
NA,
EU,
JP,
CN;
final String url;
NormalEndPoints () {
// Grab the configured property connected to my name.
this.url = getProperty(this.name());
}
#Override
public String getURL() {
return url;
}
}

Regarding alternative to interfaces and acessing with static imorts

I was going through a research in which I dont want to store the constants in the interface itself, so I was looking for alternatives like enums but another approach I have found is that ....t instead of using an interface, use a final class with a private constructor. (Making it impossible to instantiate or subclass the class, sending a strong message that it doesn't contain non-static functionality/data. and we can also take the advantage of static import in that case
Public final class KittenConstants
{
private KittenConstants() {}
public static final String KITTEN_SOUND = "meow";
public static final double KITTEN_CUTENESS_FACTOR = 1;
}
two independent things. 1: use static imports instead of abusing inheritance. 2: If you must have a constants repository, make it a final class instead of an interface . Please advise is this approach is correct..!!
To avoid some pitfalls of the constant interface (because you can't prevent people from implementing it), a proper class with a private constructor should be preferred (example borrowed from Wikipedia):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
And to access the constants without having to fully qualify them (i.e. without having to prefix them with the class name), use a static import (since Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
Please show how we can do same ting with enum also..!
You can achieve your "constants" via an enum:
public enum Animal {
Kitten("meow", 1),
Puppy("woof", 2);
private final String sound;
private final double cuteness;
Animal (String sound, double cuteness) {
this.sound = sound;
this.cuteness = cuteness;
}
public String getSound() {
return sound;
}
public double getCuteness() {
return cuteness;
}
}
To use:
String sound = Animal.Kitten.getSound();
double cuteness = Animal.Kitten.getCuteness();
The simple answer is that you can't do that with an enum. An enum defines a set of related constants with the same type.
What you have in the KittenConstants case is a set of constants with fundamentally different types. This doesn't fit the enum model. (If you change the problem a bit; e.g. by generalizing over different kinds of SFA, you can make it fit ... as #Bohemian does ... but if that's not what you are trying to achieve, enum is not the right solution.)
What you have in the Constants case is a bunch of named floating point constants that you want to use as values. (All the same type ... which helps!) Now you could declare them as an enum as follows:
public enum Constants {
PLANCK_CONSTANT(6.62606896e-34),
PI(3.14.59);
public final double value;
Constants(double value) {this.value = value);
}
The snag is that you need to use ".value" to access each named constant's numeric value; e.g.
import static Constants.*;
....
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT.value / (2 * PI.value);
}
.... which is kind of ugly, and I don't think there is any way around the ugliness.
Bottom line - enums are not an ideal replacement for all kinds of constant.

Implement an interface with final fields or access fields directly?

Is there any advantage of NOT having a class implement an interface and instead use the final fields directly? For example:
public interface MyInterface {
int CONST_A = 16;
int CONST_B = 45;
}
Approach 1:
public class MyClass implements MyInterface {
MyClass() {
System.out.println("A = " + CONST_A);
System.out.println("B = " + CONST_B);
}
}
Approach 2:
public class MyClass {
MyClass() {
System.out.println("A = " + MyInterface.CONST_A);
System.out.println("B = " + MyInterface.CONST_B);
}
}
I was wondering if any of the approaches above has advantage of any kind over the other. One of the places this situation occurs is in Blackberry where you have your localized texts defined as an interface with keys to the strings and you need to call a system API with the key as the argument in various parts of the code.
It is considered a bad practice to put constants in interfaces and to implements those interfaces to access the constants. The reason is, many classes could implement the interface, thus providing many access points to the same constants.
So, to answer your question, I'd rather use the second solution. Even better, I'd put the constants in a final class, so that there is only a single point of access to the constants. It'd be clearer, and would be easier to refactor.
use enumeration for constants (Effective Java)
For example define like that and call KernelError.KE_UNDEFINED_CALLER
public enum KernelError {
KE_NO_ERROR(0), KE_UNDEFINED_SESSION(1), KE_UNDEFINED_CALLER(2), KE_SESSION_EXPIRED(
3), KE_NULL_VALUE_IN_SESSION(4), KE_N0_SUCH_METHOD(5);
private KernelError(int errorCode) {
setErrorCode(errorCode);
}
private int errorCode;
/**
* #return the errorCode
*/
public int getErrorCode() {
return errorCode;
}
/**
* #param errorCode
* the errorCode to set
*/
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}
If you defined constants in interfaces and, for example, define MyInterface2 which has a constant CONST_A, they conflict. Personally I think that approach 2 is easier to read.
I prefer approach 2 as it does not pollute the namespace of the using class with all possible constants. This reduces the number of code completion choices. Also, when looking at a use of a constant, the qualified name makes it obvious that it is a constant, and where that constant is defined.
That is, I prefer
interface Constants {
static int A;
static int B;
}
void foo() {
System.out.println(Constants.A);
}
to
interface Constants {
static int Const_A;
static int Const_B;
}
void foo() {
System.out.println(Const_A);
}

Categories

Resources