I've read that question & answers:
What is the best way to implement constants in Java?
And came up with a decision that enum is better way to implement a set of constants.
Also, I've read an example on Sun web site how to add the behaviour to enum (see the link in the previously mentioned post).
So there's no problem in adding the constructor with a String key to the enum to hold a bunch of String values.
The single problem here is that we need to add ".nameOfProperty" to get access to the String value.
So everywhere in the code we need to address to the constant value not only by it's name (EnumName.MY_CONSTANT), but like that (Enum.MY_CONSTANT.propertyName).
Am I right here? What do you think of it?
Yes, the naming may seem a bit longer. But not as much as one could imagine...
Because the enum class already give some context ("What is the set of constants that this belong to?"), the instance name is usually shorter that the constant name (strong typing already discriminated from similar named instances in other enums).
Also, you can use static imports to further reduce the length. You shouldn't use it everywhere, to avoid confusions, but I feel that a code that is strongly linked to the enum can be fine with it.
In switches on the enum, you don't use the class name. (Switches are not even possible on Strings pre Java 7.)
In the enum class itself, you use the short names.
Because enums have methods, many low-level codes that would make heavy use of the constants could migrate from a business code to the enum class itself (either dynamic or static method). As we saw, migrating code to the enum reduces the long names uses even further.
Constants are often treated in groups, such as an if that test for equality with one of six constants, or four others etc. Enums are equipped with EnumSets with a contains method (or similarly a dynamic method that returns the appropriate group), that allow you to treat a group as a group (as a secondary advantage, note that these two implementations of the grouping are extraordinarily fast - O(1) - and low on memory!).
With all these points, I found out that the actual codes are much much shorter !
With regard to the question about constants - enums should represent constants that are all the same type. If you are doing arbitrary constants this is the wrong way to go, for reasons all described in that other question.
If all you want are String constants, with regard to verbose code you are right. However, you could override the toString() method return the name of the property. If all you want to do is concatenate the String to other Strings then this will save you some extra verbosity in your code.
However, have you considered using Properties files or some other means of internationalisation? Often when defining dets of Strings it is for user interface messages, and extracting these to a separate file might save you a lot of future work, and makes translation much easier.
Related
I have lot of static/constant data which I want to store, this data is also related with each other. I can use lot enums referencing each other forming a tree or a graph. Or simply use tables or database enums and store values in them and create corresponding classes and respective relationships. The data I have is constant and is certainly not going to change. I might have to also consider internationalization in near future. I will be using this constant data as filter to various other data.
I am tempted to use enums as it gives me immutability by default, but seeing the complexity of relationship between data, like I might have to sacrifice with inheritance, I am also little apprehensive of enums. And populating these enum classes from database and internationalization might be little more tricky. And at later stage hoping that it will scale and embrace the complexity with ease are the areas of concern as I would not like to revert from the mid way.!
---Update---
I have not seen examples of enums related(associations) with each other, containing fields of complex types referencing other enums. Can in this type of cases enums replace classes when data is constant.
Is there any objective way to look at this problem.
To understand better, I have similar classification like below.
Animal Kingdom having tree hierarchy
While this Question is likely too broad for Stack Overflow, a few thoughts.
Enums
You may not fully understand the enum facility in Java. See the Oracle Tutorial, and see the Enum class doc.
An enum is a class, a regular Java class, a subclass of Enum. The only thing special is that syntactic sugar that automatically instantiates the static instances you define and name. Otherwise, they are normal classe:
Your enums can carry member variables.
Your enums can have constructors, and you can pass arguments to those constructors.
Your enums can offer other methods, and you can pass arguments to those methods.
You can even pass instances of one enum as arguments to methods of another enum’s instances – just as you might pass instances of an enum to instances of other non-enum classes. Each enum instance is just an object, plain and simple, saved as a static reference on the enum-defining class.
Example:
public enum Food { HERBIVORE, OMNIVORE, CARNIVORE ; } // Syntactic sugar for automatically instantiating these named static instances of this class type.
…and…
public enum Animal {
RABBIT( Food.HERBIVORE ) ,
DOG( Food.OMNIVORE ) ,
CAT( Food.CARNIVORE ) ;
// Member variables.
public Food eats ;
// Constructor
Animal( Food foodType ) {
this.eats = foodType ; // Assign an instance of another enum to this instance of this enum.
}
}
Limitations of enums
While more powerful and useful than in other languages, there are limitations.
Compile-time
Firstly, enums are defined at compile-time. If your values change at runtime, perhaps you want to add or delete items, then enums are not appropriate.
Permanently in memory
Also, enums are static. This means when first used, all the objects of that enum class are instantiated immediately and held in memory throughout the execution of your app. So they are never retired from memory until program ends. So having an enormous number of them might be a burden on memory.
Understand that your can collect enum instances. See the EnumSet and EnumMap classes for fast-to-execute and low-memory usage collections of enum instances. Search Stack Overflow for much coverage on this topic. And be aware that every enum carries a values() method that returns an array of its values, yet this method is mysteriously not listed in the JavaDoc.
As for your mention inheritance, your enums by definition are subclasses of Enum class. So they cannot inherit from any other class you may have in mind, as Java does not support multiple-inheritance. Your enums can implement one or more interfaces. In later version of Java, an inheritance can carry implementation code by way of new default methods, so you can pass along some code that way.
Internationalization
Internationalization and localization seems to be an orthogonal issue. You can add a method on your enum to generate localized String representation of their value. As an example, see DayOfWeek::getDisplayName and Month::getDisplayName enum methods.
Database
If you want to dynamically define your values at runtime, or you have zillions of them, then a database is the way to go. A serious database such as Postgres is designed to manage memory, handle concurrency, and execute efficiently.
You can even combine enums with the database. For example, localization. You might have enum values defined at compile-time, but their getDisplayName method does a lookup into a database to find the French or Arabic translation. That translation value in the database can be updated during runtime by running SQL INSERT or UPDATE commands via JDBC.
Recursive hierarchical relationships
If you are trying to represent relationships of a hierarchy of arbitrary depth, that is a whole other topic I'll not address here other than to say that is often implemented with recursion. Search Stack Overflow and other sources to learn more.
As a rule of thumb, I only involve a database when the values are likely to change faster than code release cycles, and when it's possible or likely that someone who is not me is going to change them. Making the code depend on a running (and available) database means that when some DBA takes the database down for maintenance then your application can't be started.
This question already has answers here:
private final static attribute vs private final attribute
(22 answers)
Closed 8 years ago.
I've created an interface with the following code
final static char RIVER = '~';
final static char PATH = 'Y';
The list will increase (not hundres or even tens but maybe at most 15 symbols)
Originally I was just coding the values directly into the object but I started wondering why I couldn't just create a single file with the global constansts (for the symbols on the map and only the symbols) for easy access.
I'm aware that per OO logic, encapsulation is how we should program. At the same time, final static variables exist so surely they do have a purpose.
My question then is there a reason for me to avoid using the global constants and go back to putting each symbol with each object? Does global constants have a role to play within OO programming at all or is it purely for Procedural Programming?
This is a project that only I will ever work on however I am using as a testbed to improve my standards and as such I would like to use the best method possible (in terms of standard).
Defining global constants in an interface is an anti-pattern. Either use classes to define constants and then use static imports. Or simply use enums, which gives more flexibility.
Defining global (public static) constants is okay. It helps to keep you code clear and maintainable, by giving certain values meaningful names.
What you should not do, is define global constants in an interface and then add an implements-clause to each class that uses these constants. The reason for this, that you pollute the public signature of your class in this way. Instead, alsways refer to the constants by their full name (e.g. SomeClass.SOME_CONSTANT) or statically import them (import SomeClass.SOME_CONSTANT).
I would not define all global constants in one single file however, but define each of them in the class or interface that makes the most sense, for example because they define methods that return these constants or where the constants are typical arguments.
There are several benefits in use the constants, these are some of them:
Readability: If you hard code the number, when you or some other programmer have to use the code, they have to know what the value means. If a constant is used, a meaningful name is provided.
Reusability: If the same constant needs to be used in several place, when a modification is needed, you only have to change the value in one place instead of all the places where the constant is used.
Maintainability: If you have your constants in a single place instead of multiple places in the code, it is easier to modify.
It is considered a bad practice to use interfaces to hold the constants, use classes instead. If the constants are related with the class, you can define the constants within the class. If they are general purpose constants and used in several classes, you can create an utility class to hold all the constants.
public class MyUtilityClass {
public static final int MY_INT_CONSTANT = 1234;
public static final String MY_STRING_CONSTANT = "example";
...
/* Create a private constructor to avoid creation of instances of this class */
private MyUtilityClass() {
}
}
Global constants are absolutely fine.
That having been said, do not even try programming without the maximum number* of compiler warnings enabled. If you had enough warnings enabled, your compiler would be telling you that fields in interfaces do not need to be declared final and they do not need to be declared static.
(* warnings that make sense. Every compiler has its own set of warnings that are rather nonsensical and best disabled, but these are generally few.)
Encapsulation is the mechanism which protects you from changes - for example, changing the implementation of a class, will not affect the rest of your code as long as the interface (the public or protected methods) does not change.
So you can apply this reasoning to your case. Will future changes of these constants affect the rest of the code? If not, then putting all those constants as final static instances in a single class is fine. But think of this. What if you want to change how you represent your map? (from the names of the variables I assume you're using them to represent a map) Maybe you want to use special objects which also have their own behaviour, not just how to represent them on the map. Then maybe you'll want to abstract those in new classes, and not use constants anymore. And this will affect all the code where you reference these constants - probably lots of classes.
Of course, you can start with this simple representation, and if at a later point you find it's not working anymore, then you can switch. This is what I would do. I don't think it's wrong.
I have a question about String storage.
I use a code generation framework (In java, generates java) which uses a lot of strings that I want to organize in some way.
I was thinking of having the strings in functions, which will allow me to add javadocs and such to the strings. There will be a lot of functions, I planned to split them in different classes depending of the type (like methods or classes for example). I do not have any database so it must be in the project.
How do I best do this? With static final on everything it would be easy to access, but is there any downside to this? (I don't use multithreading btw)
I they are constant Strings, then definitely make them constant by declaring them static and final. And declare these constants where they logically belong, i.e. in the class that depends on this constant for its logic.
I don't see any downside, on the contrary.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am maintaining some Java code that utilizes an interface (let's call it BunchOfConstants) to simply store an abundance of public static final Strings. Occasionally these string names change or string names are added / removed. (which causes a bit of a headache for maintanance)
The only current use for this interface is to compare to input later in a big ugly if/then construct like this:
if(BunchOfConstants.CONSTANT1.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT2.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT3.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}
...
I thought it would be more elegant to create a class that implements Iterable or even a class that stores this data in a hashMap.
I can not figure out why the original developers decided to use an interface for this design as the interface is never actually implemented anywhere. Does anyone have any input?
Would you agree that an iterable class with these members as constants would be more appropriate?
Use enums. Then get myenum.values() and then apply a for-each loop over the values.
I would consider using enums instead as constants are not type safe (e.g., they are just ints, or strings, etc.).
This (having dedicated interface for storing constants) was a fairly common way of storing constants before the era of enums. (Pre Java 5 times.) It saved you the hassle of prefixing your constants with the containing class name. I personally never really liked this practice, but this is the reason people did it.
As for what it can be replaced with:
An enum and a switch/case construct. This requires the least modification but only has modest benefits in readability. It does give you type and value safety, plus you can get warnings out of your IDE if you forget to handle a possible value (no case for it and no default block either).
A properties file. This obviously only works if you don't want to branch based on your constant values. (I.e. if your constants don't have to appear in your source code.) This is important, otherwise you'd end up with a secondary set of constants and a properties file, which is as bad as it gets.
A doSomeStuff() factory. For this you have to wrap your doSomeStuff() implementations in separate operation classes and you can configure your factory either statically or from a properties file. (via a constant value->operation class mapping). This is the most "enterprisey" solution, which means that although it looks nice and is very flexible, a lot of the time it is an overkill.
I think this is a good candidate for enum
Well, this looks like the Constant Interface antipattern and maybe should not be used. Using an enum might be a way as suggested, or at least using a final class with private constructor.
If you want to have different implementations for doSomeStuff based on the input string, you might also consider using the strategy pattern, i.e. have a Map<String, Strategy> and then lookup the strategy for whatImLookingFor. If you found the strategy, execute its doSomeStuff, otherwise handle the "not found" case.
I would suggest you to use a property file to store all your constants. This way you can load your properties into a HashMap as you suggest in your question.
Note that property support is brought natively with java: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html
Well, enums are the way to go ... but if the 'dosomestuff' is semantically dependent upon the specific value then why not add a 'dosomestuff' method to the enum itself. That is one that this is really great about Java enums - they are not merely data but as all good objects they have semantics. Then you just loop over the enums invoking dosomestuff(whatIamLookingFor) and whatever happens happens.
Hard to say.
Yes, I agree, that it will be more elegant - at least for you. But think, what the next programmer will think about it. It will be even more complicated.
Previously mentioned strategy pattern and java's enum are definitely better solution, but since you are maintaining this code, I'm not sure if your boss will be happy with time consuming refactoring. My advice would be to use enums - not so big code change.
I have an interface, GenericExpression, that gets extended to create expressions (ie AndExpression, OrExpression etc.).
Each GenericExpression implementation has a string that represents it (ie "&", "+", etc.) (stored as a static variable "stringRep")
Is there any way to take a user input String and check if it represents a GenericExpression?
If not (seems likely this is the case), is there any way to achieve a similar effect with a refactored design?
Thanks!
EDIT: Offered a little bit more detail above.
Also, the end goal is to be able to arbitrarily implement GenericExpression and still check if a string represents an instance of one of its subclasses. As such, I can't just store a map of implementation - string representation pairs, because it would make make it so GenericExpression is no longer easily extendible.
Also, this is homework
Well I think you will need to define somewhere what expressions are supported by your program. I think the best way is to use a map, where you map your interface to strings. That way you can easily look up an expression with its representing string. Where you will define this map is dependant on your design. One possibility is a static method in a helper class that resolves expressions to a string like:
Expressions.get("&").invoke(true, false);
Where get is a static method on Expressions that looks up the desired expression in a static map. You will have to initialize this map in a static initializer, or let the expression instances add themselves on creation.
EDIT:
(I wanted to comment this on an answer but it seems to be deleted)
Personally I don't like the idea of classes registering themselves. It gives me the feeling of not being in control of my code. I would prefer to instantiate the classes in the Expressions class itself. The code for registering a class must be written for every new subclass anyway. I prefer to centralize this code in a single class so if I want to change logic or refactor, I only have to touch one class.