In Java, an Enum can do the great things that Enums do, but can also have methods (behavior and logic). What advantage does that have over using a class using an enum? Simple examples to illustrate the point would also be welcome.
Here's a simple example:
enum RoundingMode {
UP {
public double round(double d) {
return Math.ceil(d);
}
},
DOWN {
public double round(double d) {
return Math.floor(d);
}
};
public abstract double round(double d);
}
Enum types are also a great way to implement true singletons.
Classic singleton patterns in Java typically involve private constructors and public static factory methods but are still vulnerable to instantiation via reflection or (de-)serialization. An enum type guards against that.
I'm not quite sure where the title of the question fits in with the rest of it. Yes, Java enums have behaviour. They can have state too, although it should really, really be immutable state. (The idea of a mutable enum value is pretty scary IMO.)
An enum in Java is a fixed set of objects, basically. The benefit is that you know that if you have a reference of that type, it's always either null or one of the well-known set.
Personally I really love Java enums and wish C# had them too - they're much more object-oriented than C#'s enums which are basically "named numbers". There are a few "gotchas" in terms of initialization order, but they're generally fab.
Because the enum instances are singletons, you can use them in switch statements or with == to check equality.
Basically, Java enums are classes (I don't believe there is a difference at the bytecode level), with the additional benefit of having a known fixed set of possible instances and being able to use them in switch statements.
You can emulate the "known fixed set of possible instances" with regular classes (the "typesafe enum" pattern described in countless books and articles), but it's quite some work (repeated for every such class) to get it to work really correctly in regard to Serialization, equals() and hashCode(), and perhaps some other things I forgot. Language-level enums spare you that work. And, as mentioned above, only language-level enums can be used in switch statements.
In our project, we're using Enums for a few things, but perhaps most prominently for i18n purposes - each piece of shown text is given an Enum. The Enum class has a String-returning method that inspects the Locale that is being used, and picks the correct translation from a collection of translations on runtime.
This serves as a dual-purpose - you get code completion from your IDE, and also never forget to translate a string.
The usage is very simple, to the point that it's almost rendundant to give an example, but here's how one might use the translation-enum
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
Or, if you want to be fancy, have the Enum accept arguments, which will, with some magic string manipulation, be inserted in a marked position in the translations string
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Take a look at java/joda time classes, where enums do hell of a lot of job.
Here is an example of java.time.Month:
public enum Month implements TemporalAccessor, TemporalAdjuster {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
private static final Month[] ENUMS = Month.values();
public static Month of(int month) {
if (month < 1 || month > 12) {
throw new DateTimeException("Invalid value for MonthOfYear: " + month);
}
return ENUMS[month - 1];
}
// About a dozen of other useful methods go here
}
Related
Can we pass objects to enum abstract methods and do a computation in enums? Here is a scenario, I have four constants and each one have their own value assigned to it. Based on the constants I will do the computation in my method.. Instead I would like to do the computation in enum and would like to get the response. To do the computation in enum I have to pass two/three reference objects to the enum methods...
ex: Consider school as enum, constants are TEACHER(LOWLEVELACCESS), STUDENT(NOACCESS), OFFICEADMIN(OFFICEACCESS).
In enum, I have abstract method process which is receiving USER POJO , strings as arguments and update some fields in the object and return the same USER POJO (with updated) to the caller. By this I can sync up the constants and their logic in enum itself.
So my question,
Is it alright to have this implementation in enum? (I have seen most of the examples treat enums to store constant values not using them for any computation)
This computation can be done by using methods in classes, what is the benefit if I do the computation in enum methods?
Is it possible to create getter/setter method in enum?
Thanks In Advance!!
IMHO:
Is it alright to have this implementation in enum?
Yes - I do it all the time.
enum Ops implements Op {
Nop{
#Override
public int filter(int old, int now) {
// Unchanged.
return now;
}
},
Diff{
#Override
public int filter(int old, int now) {
return a(now)
| (Colour.MidGrey + (r(now) - r(old))) << 16
| (Colour.MidGrey + (g(now) - g(old))) << 8
| (Colour.MidGrey + (b(now) - b(old)));
}
};
}
This computation can be done by using methods in classes, what is the benefit if I do the computation in enum methods?
The code for the functionality is in one place. This is always a good thing.
Is it possible to create getter/setter method in enum?
Yes - but don't. Remember that there is one instance of each enum for the lifetime of your code. Adding/removing functionality on a global object is very likely to hurt you later.
Is it alright to have this implementation in enum?
It is a design choice.
Enum brings some advdantanges to provide service operations.
Enum values are singletons out of the box, these are self explanatory, there are memory efficient, etc... but have also some limitations, you cannot directly derive from an enum, so you should introduce an interface behind the enum if you want to be able to test your code and avoid coupling the client classes that do the computation with the enum ... if later you change your mind about the enum usage.
This computation can be done by using methods in classes, what is the
benefit if I do the computation in enum methods?
You reason in terms of objects. You don't need to create a service and indirection in the code since the enum that is a domain object does the computation.
The enum values and the processings associated make part of the same concern. So, gathering them is not necessary a bad smell.
Nevertheless, be aware if you start to write a lot of processing that do very different things in the enum methods, you should probably get them out the enum.
This is a bad smell as the enum should not become a god object.
Is it possible to create getter/setter method in enum?
Providing data, yes but setting data of the enum : no, you must not.
Otherwise you build a stateful service and you risk to finish with synchronization concerns.
Enums are defined to be final. Computations are allowed as far as the result is equal for the same input.
You also can modify the input instance, but you should not define any setter in your enum due the enum is not immutable in that case.
See also Example 8.9.2-4 here
This question already has answers here:
What's the advantage of a Java enum versus a class with public static final fields?
(18 answers)
Closed 8 years ago.
I am getting confused regarding Enum.
Where and how to use Enum?
If I will use Enum instead of constant then what could be the benefit?
Could someone please explain to me?
The primary advantage is type safety. With a set of constants, any value of the same intrinsic type could be used, introducing errors. With an enum only the applicable values can be used.
An Enum class is used to specify a range of constants that will be frequently used within an application.
From http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html:
You should use enum types any time you need to represent a fixed set of constants.
Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.
A constant class (assuming this is what you are talking about), is really specified for one solid object that you wouldn't change. Technically, an Enum class is a constant class with more definitions, but an advantage to an Enum class is some pre-defined functions that you would have to define in your own constant class. However, you should also note that this may be overkill for small, singleton examples.
Additionally, Enum classes are type-safe, whereas static fields aren't. Compile time error checking is now possible, versus the run-time potential errors that will occur with a constant class. This furthermore improves readability, because instead of having errors where an index of a list of constants is unavailable. This is all well explained in this post, by the current best answer.
As of Java 8.0 the keyword "constant" does not exist.
If you mean "const":
This keyword is in the known keywords in Java (from the beginning until today - 8.0),
but it has no use and any compiler shouldn't compile if it find's this keyword.
Enumerations:
Use them when you have specific logical values and don't want to handle them in String,
like:
public enum AcceptableColours {
BLACK,
WHITE,
GREY
}
It's much safer during development time to match enum values
AcceptableColours currentColour = object.getColour;
if (currentColour == acceptableColours.BLACK) {
// do something
} else if (currentColour == acceptableColours.WHITE) {
// do something different
}
than to match string values
AcceptableColours currentColor = object.getColour;
if (currentColor.equals("black")) {
// do something
} else if (currentColor.equals("white")) {
// do something different
}
... imagine huge applications with much more variations on enum values (like banking software, insurance software, ...), where it's much easier to misspell some string values,
and voilĂ , happy debugging...
My question concerns a specific design convention for methods in Java... but really it would apply to C++, C# and others as well. I don't know what this convention is called, but if there is a standardized convention, I would like to know how to find it. In other words, I wish to describe this convention as I have encountered it and be directed to a place where I can learn more.
Consider java.util.Calendar, specificlaly its child, GregorianCalendar. It has an interesting "getter / setter" convention. Let's say that you instantiate this object:
GregorianCalendar cal = new GregorianCalendar();
The fields of cal now describe the instant in time (down to the millisecond) at which the constructor was called.
Now let's say that you want to access the year field or the month field. You would use the following getters.
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
Notice that it's not cal.getYear() or cal.getMonth(). It looks like there is only one getter method for this class and that the return value is determined by the parameter naming the desired field. I would imagine that within the class there is an enum set up to list the fields... and that the getter function itself is composed of some kind of switch statement.
This type of architecture is not described in any of my books... it is however something that I've been using in my current work... but I've been doing it "my" way (basically just making it up as I go along). If there is a standardized way of doing this that other people use... I'd sure love to know it. Specifically, using enums and switch statements to control the execution of methods.
Thanks so much for your time! This is my first question on this site... I have been a long time lurker though. :)
First, note that the two approaches to API design are not mutually exclusive: one could have both a "get by index" and a "get by name", i.e.
int y1 = cal.get(Calendar.YEAR);
int y2 = cal.getYear();
The primary driving force behind getters controlled by an int constant in the Calendar class is uniformity: it lets users of the Calendar class, such as the date formatters, build code that accesses the calendar by index, without further interpretation. For example, if you wanted to implement a formatter that takes a format string and stores a data structure to pull data from a calendar, you would be able to do it with an array of integers: "dd-mm-yyyy" would become int[] {Calendar.DAY, Calendar.MONTH, Calendar.YEAR}, and you would be able to get the data from calendar with a simple for loop.
Note that one of the reasons why Calendar uses integer constants instead of enums is backward compatibility: that Java did not have enum at the time when the Calendar class has been introduced.
Also note that you do not need a switch statement on an enum or int constants to implement Calendar's getters and setters: they can be implemented as direct reads and writes of the calendar component array.
Actually those are not enums. Those are integers instead. Here is the source code of the Calender get method:
public int get(int field)
{
complete();
return internalGet(field);
}
But having a single method accepting a ENUM and returning different values based on that, is good practice.
As far as the design pattern goes, IMHO it is a variation of Factory pattern.
I'm not actually aware of a name for this specific design, although I've seen it used in a few places. It's certainly not one of the standard "Design Patterns" and is really too small to qualify as a design pattern in its own right. It's just a different way of achieving encapsulation over the more traditional way with multiple getters and setters.
If I was to call it something it would probably be something like "flexible getter" or "extensible getter". I.e. "Rather than having multiple setters lets have one flexible getter"
If I was implementing something like this I would probably use the strategy pattern to do it though:
public abstract class Getter<T> {
private T getData(MyCalendar ob);
}
public static final Getter<Integer> MONTH {
Integer getData(MyCalendar ob) {
return ob.month;
}
}
Then your get method just looks like:
<T>public T get(Getter<T> toGet) {
return toGet.getData(this);
}
This uses polymorphism to fetch the data rather than a massive switch statement. It is fully flexible and extensible while still being type safe, etc.
Let's say I have a constants class containing 200+ static fields :
class AnimalConstants {
static final int AARDVARK = 1;
static final int ANTELOPE = 2;
static final int BEAR = 3;
...
...
static final int ZEBRA = 200;
}
Can anyone explain if there are any negative impact on performance and memory from using such classes.
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
Would it be better or worse if I implement the constants as an Enum class?
I don't think the impact is performance or memory.
I think it has to do with things like readability of code, keeping constants close to where they're used, and fundamental understanding of your problem.
I prefer to declare constants closer to where they're used. I believe they're easier to understand that way.
I would be surprised if the real constants that you claim number 200+ are truly related. If they are, they belong together in one place. If not, I'd say that they should be broken into smaller pieces and declared closer to where they're used.
I'll bet there's more context than your contrived example that would change responses if known.
Sure , enums are great. But see my other comments first.
Of course enum implementation is more ponderous than bunch of int constants but using enum:
you don't need to hardcode actual values of Animals (in your case) that can change later
you don't need to hardcode total number of Animals and you can simply iterate through all animals
methods with parameter of this enum will be understood correctly (foo(Animal animal) is better than foo(int animal))
you can add additional functionality to your enum values later, e.g. internal value isMammal
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
--> That would be a Constant Interface Pattern. If we use interfaces for constant and it is implemented by all classes but if you are developing an API, it is something like you are exposing your implementation details. Above wiki link explains this very well.
In both approach(Interface or Class) I would suggest using final class, create constants and do static import for constants wherever necessary.
Would it be better or worse if I implement the constants as an Enum class?
--> With Enums, this would be the best approach.
Changing any value that has already been compiled into another class may require a full build.
Addendum: See Is it possible to disable javac's inlining of static final variables? for a more thorough examination.
Yes it is okay to create a large number of constants. It is hard to discuss negative impact because we don't know any alternatives because we don't have your functional requirements.
But be assured that the compiler is written to work well with code written by humans. Having a bunch of fields is probably going to be okay.
I feel that constants can be very nice as it can be used in switch case since JDK7, you can compare with == and the variable name can be informative.
Can enum be even better? Yes it can. Explore the features of enums and see if anything is appealing to you
For your kind of vars (Animal Types) i suggest you to use an Enumerator instead of a class. With the number of vars using it shouldn't be a problem for performance as you're only using int primitive. The problem would have occurred if any var has been a class, that are more memory demanding to maintain their structure. I hope to have clarified your doubt (Sorry for the poor english, i'm a little rusted)
Is it confusing to design an API with multiple ways of achieving the same outcome? For example, I have my own Date library (which is a simple wrapper around the Java Date/Calendar classes to distinguish a year-month-day, Date, from an instant-in-time, Instant and provide mechanisms to convert between the two). I started off with one method to create an instance of a Date:
Date.valueOfYearMonthDay(int year, int month, int day);
But then I found that the resultant code using the API was not very readable. So I added:
Date.yearMonthDay(int year, int month, int day)
Date.ymd(int year, int month, int day)
Date.date(int year, int month, int day)
Then I started getting fluent:
Date.january().the(int day).in(int year);
(I find that the fluent version is really useful for making readable tests). All these methods do identical things and have accurate JavaDoc. I think I've read that a strength of perl is that each programmer can choose exactly which method he/she prefers to solve something. And a strength of Java is that there is usually only one way of doing things :-)
What are people's opinions?
I've been doing academic research for the past 10 years on different issues that have to do with API usability in Java.
I can tell you that the statement about having one way to do things in Java is fairly incorrect. There are often many ways to do the same thing in Java. And unfortunately, they are often not consistent or documented.
One problem with bloating the interface of a class with convenience methods is that you are making it more difficult to understand the class and how to use it. The more choices you have, things become more complex.
In an analysis of some open-source libraries, I've found instances of redundant functionality, added by different individuals using different terms. Clearly a bad idea.
A greater problem is that the information carried by a name is no longer meaningful. For example, things like putLayer vs. setLayer in swing, where one just updates the layer and the other also refreshes (guess which one?) are a problem. Similarly, getComponentAt and findComponentAt. In other ways, the more ways to do something, the more you obfuscate everything else and reduce the "entropy" of your existing functionality.
Here is a good example. Suppose you want in Java to replace a substring inside a string with another string. You can use String.replace(CharSequence, CharSequence) which works perfectly as you'd expect, literal for literal. Now suppose you wanted to do a regular expression replacement. You could use Java's Matcher and do a regular expression based replacement, and any maintainer would understand what you did. However, you could just write String.replaceAll(String, String), which calls the Matcher version. However, many of your maintainers might not be familiar with this, and not realize the consequences, including the fact that the replacement string cannot contains "$"s. So, the replacement of "USD" with "$" signs would work well with replace(), but would cause crazy things with replaceAll().
Perhaps the greatest problem, however, is that "doing the same thing" is rarely an issue of using the same method. In many places in Java APIs (and I am sure that also in other languages) you would find ways of doing "almost the same thing", but with differences in performance, synchronization, state changes, exception handling, etc. For instance, one call would work straight, while another would establish locks, and another will change the exception type, etc. This is a recipe for trouble.
So bottom line: Multiple ways to do the same thing are not a good idea, unless they are unambiguous and very simple and you take a lot of care to ensure consistency.
I'd echo what some others said in that convenience methods are great, but will take it a step further - all "convenience" methods should eventually call the same underlying method. The only thing that the convenience methods should do other than proxy the request is to take or return variables differently.
No calculations or processing allowed in the convenience methods. If you need to add additional functionality in one of them, go the extra mile and make it happen in the "main" / "real" one.
Its fine to provide convenience methods, the real problem is if each entry point begins to do behave in subtly different ways. Thats when the api isn't convenient anymore. Its just a pain to remember which way is "right," and documentation starts saying "the recommended way is..."
If Date.yearMonthDay() began to validate the date while Date.ymd() didn't, that'd be a problem. The same goes for if each begins supporting different "features" - Date.yearMonthDay() could take non-gregorian dates, and Date.date() could take a non-gregorian dates so long as a 4th object is given that tells the calendar type.
First, please don't invent your own date library. It's too hard to get right. If you absolutely have nothing better to do, be sure to read -- and understand -- Calendrical Calculations. Without understanding Calendrical Calculations you run a big risk of doing things wrong in obscure corner and edge cases.
Second, multiple access to a common underlying method is typical. Lots of Java library API methods state that they are simply a "wrapper" around some other method of class.
Also, because of the Java language limitations, you often have overloaded method names as a way to provide "optional" arguments to a method.
Multiple access methods is a fine design.
If these do the exact same thing:
Date.yearMonthDay(int year, int month, int day)
Date.ymd(int year, int month, int day)
Date.date(int year, int month, int day)
I think that is bad form. When I am reading your code, I have no clue which one to use.
Things like
canvas.setClipRegion (int left, int top, int right, int bottom);
canvas.setClipRegion (Rect r);
are different in that it allows the caller to access the functionality without having to figure out how to format the data.
My personal opinion is that you should stick with one method to do something. It all 4 methods ultimatly call the same method then you only need on of them. If however they do something in addition to calling them method then they should exist.
so:
// This method should not exist
Data yearMonthDay(final int year, final int month, final int day)
{
return (valueOfYearMonthDay(year, month, day));
}
The first methid in addition to the fluent version would make more sense. But the yearMonthDay, ymd, and date methods should go.
Also, differnt langauges have different goals. Just because it makse "sense" in Perl doesn't mean it makes sense in Java (or C#, or C++, or C, or Basic, or...)
I find that the fluent version is really useful for making readable tests.
This is a little bit troublesome because I worry that you might only be testing the fluent version. If the only reason methodX() exists is so you can have a readable test for methodY() then there is no reason for one of methodX() or methodY() to exist. You still need to test them in isolation. You're repeating yourself needlessly.
One of the guiding principles of TDD is that you force yourself into thinking about your API while you're writing your code. Decide which method you want clients of your API to use and get rid of the redundant ones. Users won't thank you providing convenience methods, they'll curse you for cluttering your API with seemingly useless redundant methods.