What are the drawbacks of enums in Java? - java

While looking at jhipster, I have stumbled across the following class
public final class AuthoritiesConstants {
public static final String ADMIN = "ROLE_ADMIN";
public static final String USER = "ROLE_USER";
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
private AuthoritiesConstants() {
}
}
I was wondering why they did not use enums like for example
public enum AuthoritiesConstants {
ROLE_ADMIN,
ROLE_RESPONSABLE,
ROLE_MANAGER,
ROLE_COLLABORATEUR
}
Are there any drawbacks using enums?

One possible answer is that enums were introduced in Java 1.5. While this seems like ancient history, some libraries still use string constants or numeric constants for compatibility reasons.
Another possible answer is that those are not really semantically enum elements, but constants used by an external interface and are only ever accessed via their string value. In such cases, using enums and calling name() each time would be redundant.
Other than that, you should never use enums over string constants in such cases.

1. It is much like class it’s extend java.lang.Enum so you can’t extend
other enum. Another potential problem is you don’t get along with
Expression Language (EL) in JSP.
2. There are things that can be done in normal classes but maybe you can
not do with enum class because of it is a special class. For example,
accessing a static field in the constructor that not possible with
enum.
3. When you working with JSP then you can not be accessing enums nor
calling enum constants because it’s not supported (which is possible
after EL version 3.0)
These are Major drawback.
.

If a value is only really meant to be referenced as a String, then I would leave it as a String constant for simplicity's sake.
Enums are more complicated than String constants with additional functionality and nuance. Check out this question about the difference between an enum's toString and name methods.
If you ever need to change the value of a String constant, it is a one-line change. With an enum it can get more complicated due to having separate values for name and toString, and those values possibly being used in conditional logic.

Related

Static final field in a class vs Interface field in java

I need to create a 100 or more static final constants in my application and I can achieve this is following two ways as per my understanding:
Creating a simple java class and create static final field in that
Creating an interface an put all variable in that because all field in an interface is implicitly static final
I have these question in above approach:
Which one is right approach to achieve this?
Which one is memory efficient approach?
Is there any design pattern to achieve this?
You can refer to many books about the topic.
I will quote a good one: "Effective Java"
Item 19: Use interfaces only to define types
The constant interface pattern is a poor use of interfaces. That a
class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to
leak into the class’s exported API. It is of no consequence to the
users of a class that the class implements a constant interface
you can even check where JDK mostly constants are declared..
Math.PI for example is declared in the class Math and not in an interface
and as an exception you can see constants like in the java.io.ObjectStreamConstants but again the Books are there to help:
From effective java again:
There are several constant interfaces in the Java platform libraries...
These interfaces should be
regarded as anomalies and should not be emulated.
I would not be thinking should they be in an interface or class, but more about the constants and their meaning.
I would not recommend putting all your constants in one place for the sake of keeping them together. If for instance a constant is directly related to a class then would say put it in that class. I have worked with code where all the constants ate bundled into one class, and I don't thing it is a good approach.
Have you considered approach with ENUM or it doesn't fit in your case?
I think, the approach with ENUM can gives you some benefits over constants.
Why use Enums instead of Constants?
I think that convenient way is to keep them in one place, if they are have common nature. Anyway, they should be grouped by some attribute. You can create class for them like this:
public final class Consts {
public static class GroupA {...}
public static class GroupB {...}
//and so on
}
With groups this class becomes much readable and a little bit better manageable. About memory consumption, try to use primitives for your constants, because they do not require additional space for meta information.
You can create Final or static constraint much as you like just by declaring field inside interface class so i would like to go with your option number 2

Should static methods be separated from Classes with instance methods?

As a general convention, should static method(s) be separated into another class from a class with instance methods?
Is there also an example of your reason?
There is no general convention that dictates that a static method must be separate from a non-static method. In fact, if the two methods are related enough to one another, it would be counter-intuitive to have the methods separated.
Recall what use case static methods (and fields) have: they're methods/fields that can be used without an instance of a particular class. This generally means that they hold valuable metadata or perform a useful operation that's related to their class instance, but would not require direct instantiation of that class.
Take, for example, Integer. It has the static [final] fields MAX_VALUE and MIN_VALUE. Since both of these fields contain fixed information that would not change between instantiations, it would not make sense to have to instantiate an Integer to get this information.
Integer also has the useful operation parseInt, which takes a String and turns it into an int. We shouldn't require an instance of Integer to convert from String to int, especially if we're not placing it into an instance of Integer.
The overarching convention has been to keep related methods together, regardless of if they're static or not. You can see clearer examples of this in certain Java library classes, like Integer.
It probably is a duplicate question, but no, static methods have very specific benefits that are often valuable in classes that are instantiated as objects.
There is no such convention. It's completely depends on your situation. Some class may really needs mixture of both static and non-static members.
But some times it's is seen the use of Constatns.java/ Utils.java class in some java project. You may found -
public static final double PI = 3.1416;
public static getArea(double r){}
This class contains some final static property and some final method. The purpose of these class to provide some constants or utility method all over the project.
Definitely answer would be dictated by the use case but there is no convention as such. At most you have some Utility class that may have bunch of static methods that are used by other classes as helper methods. For example to test whether a String is an email or to extract username from email etc.
Putting all static methods in a separate class would be useful while writing an API or a framework. Collections class is an example. java.lang.Math or java.lang.System is another.
Normally, define static methods in the following scenarios:
While writing utility classes .
If the method does not use any instance variable.
If any operation is in-dependent of instance creation.
If you are sure that the definition of the method will never be changed or overridden. As static methods can not be overridden.
see here - https://stackoverflow.com/a/5313383/760393

Java, interface or composition for constants class

I have a question regarding the design of my program. I have a class A that stores public constant so that i can use these constants in another class.
public static final String error_code1 = "Fatal Error";
public static final String error_code2 = "XXXX";
...
...
Between Composition vs Interface, i dont know which 1 is more suitable. From what i think, since i only need the constants for value-comparing in my program, so i think composition is enough (low coupling).
But can you guys give me some advice/arguments from software deign point of view? (cohesion, coupling, difficulties of maintenance, etc )
First of all I'd recommend you to use an enum for this case.
public enum ErrorCode {
FATAL_ERROR("Fatal Error"),
X_ERROR("XXXX");
public final String msg;
private ErrorCode(String msg) {
this.msg = msg;
}
}
If this doesn't suit you for some reason, I'd go with a final utility class with private (unused) constructor.
Regardless, since the fields are static and final, I would not consider having a reference to A or implement A to get hold of the constants.
Adding constants to interfaces is considered an anti-pattern since the primary purpose of an interface is to define behavior contracts. Use either an enum or access them directly since they are public.
I wouldn't use interface to store constant as having static members into an interface (and implementing that interface) is a bad practice and there is even a name for it, the Constant Interface Antipattern, see [Effective Java][1], Item 17:
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
I would personally go for enum and if needed i could even use it to have error code or add relevant field/method as well.
String/int/... constants in another class have one problem: they are copied into the using class' constant pool, and after that no import to the original class exists. Should you then alter a constant's value, the using class is not forced to be recompiled.
The solution would be to use an interface, and "implement" that interface; ugly maybe.
Better is to use an enum.
For open ended value domains one would not use an enumeration, but an object oriented approach:
abstract class ParseError extends RuntimeException
class ExpressionExpectedError extends ParseError
class DigitsMayNotFollowLeadingZeroError extends ParseError
..
In the javadoc one might see all child classes of ParseError. Here the classes themselves form the domain values, and an instantiation bears the actual context information. That is more OOP. Calling several methods on an object is better than having several switches on constants. An enum however may be used with categorical method too: boolean errorHandledBySkippingToNextExpr().

Is this an acceptable use of globals?

I am writing a rather complicated translation module which essentially translates between a form of logical representation and Java code. It spans several classes which are all decoupled from each other.
My problem is that I need to keep track of a rather extensive set of keywords which need to be inserted, for example, into variable names. These keywords must be accessible to all classes in the module, and be easy to change.
I understand that the use of globals is a red flag as far as design goes, but would it be acceptable in this case to create a class which does nothing but provide static access to said keywords? For example:
public final class KeyWords {
public static final String SELF = "self";
public static final String RESULT = "callResult";
// etc
}
My own thoughts is that it would work somewhat like a simple config class. I find this a lot more reasonable than using, for example, a mediator or passing some other bucket class between method calls, since the data is rather well defined and, importantly, not subject to modifcation during runtime.
OR, would it be better to put all these keywords into an interface instead, and let all my class inherit this? While it could work, it just does not feel right.
This isn't the worst thing ever, but it's somewhat out of date. If you're using Java 1.5 or above, an enum would be better; it gives you type safety, for instance.
public enum KeyWord {
SELF("self"),
RESULT("callResult")
;
public String getKeyword() {
return keyword;
}
private KeyWord(String keyword) {
this.keyword = keyword;
}
private final String keyword;
}
You're right that the "tuck them into an interface" approach doesn't feel right; an interface is about specifying behavior, which a methodless interface with static finals does not provide. Since Java 1.5, you can use static imports to get the same benefit without that "code pollution."
If you are going to be using the same set of keywords, across multiple classes that don't inherit from each other then I would suggest just creating a static class that reads in a text file that has all of these keywords in it.
If you use this method then you can use the "code once use everywhere" ideology that the pros always drone on about.
-Create a static class
-Read in a text file that has all your keywords saved in it
-write a couple functions that retrieve and compare keywords
-Use it in every class you want without worry of fragmentation.
Using this method also makes updating a snap because you can simply open the text file change add or delete what you want then it is fixed in every single class that implements it.

Creating class for defining constants

Most of the time I define constants in the same class where i want to use them.
But now i have to define all common constants in a separate class. I have seen two version of constants defining classes:
a. It will give compile time error, if you try to create object of Consts.
final class Consts {
private Consts(){}
public static final String TAG = "something";
}
b. If will throw a run time exception, if you try to create a object of Consts.
final class Consts {
public Consts(){
throw new RuntimeException();
}
public static final String TAG = "something";
}
check this class of android http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/Manifest.java
Why they have used second version?
Which one should I use and why should I go for second version?
I don't see any reason for the second version, as the first one (private constructor) does exactly what you want.
Another common idom is to make the constant-holder an interface. However, this is not universally appreciated and can lead to people implement-ing that interface, which is often considered a code smell.
From my point of view, there is no reason to use the second approach. It is misleading from the API since the class exposes a visible constructor that will throw an exception in any case. Clients may fall into that trap.
However, there are other options, too, e.g. you could make Consts an interface
interface Consts {
String TAG = "somthing"
}
This would allow for classes that implement the interface and thereby have "easier" access to the constants (without static imports). Another advantage would be, that you could use find references even if you only have the compiled classes in your IDE. Since the compiler will inline the constants into the using classes, references to TAG are hard to find. If the clients implement that interface, they can be easily lookup up. However, some coding guidline forbid that.
The next option that is possible, would be an enum. The JVM will ensure that there is only one instance for each constant in an enum class:
enum Consts {
TAG, OTHER, ..
}
You can use both, first is simpler and better because causes 'compile' errors, not runtime, i.e. you catch the problem before.
You can also make the class private in the package (not using the public modifier) and write the other classes in the package (if it's always you writing them) so that they don't instantiate that class. Yes, java is OOP, but you don't need to be pedantic. :) I've never seen anybody instantiating a class of static fields by mistake, and if he/she does, than it makes no harm.

Categories