Java using enum for constants

Attaching Values to Java Enum

announcement - icon

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

We rely on other people’s code in our own work. Every day.

It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.

Lightrun is a new kind of debugger.

It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.

Learn more in this quick, 5-minute Lightrun tutorial:

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

announcement - icon

DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.

The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.

And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.

announcement - icon

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

We’re looking for a new Java technical editor to help review new articles for the site.

1. Overview

The Java enum type provides a language-supported way to create and use constant values. By defining a finite set of values, the enum is more type safe than constant literal variables like String or int.

However, enum values are required to be valid identifiers, and we’re encouraged to use SCREAMING_SNAKE_CASE by convention.

Given those limitations, the enum value alone is not suitable for human-readable strings or non-string values.

In this tutorial, we’ll use the enum features as a Java class to attach the values we want.

Further reading:

A Guide to Java Enums

A quick and practical guide to the use of the Java Enum implementation, what it is, what problems it solves and how it can be used to implement commonly used design patterns.

Iterating Over Enum Values in Java

A Guide to Constructors in Java

2. Using Java Enum as a Class

We often create an enum as a simple list of values. For example, here are the first two rows of the periodic table as a simple enum:

Using the syntax above, we’ve created ten static, final instances of the enum named Element. While this is very efficient, we have only captured the element symbols. And while the uppercase form is appropriate for Java constants, it’s not how we normally write the symbols.

Furthermore, we’re also missing other properties of the periodic table elements, like the name and atomic weight.

Although the enum type has special behavior in Java, we can add constructors, fields and methods as we do with other classes. Because of this, we can enhance our enum to include the values we need.

3. Adding a Constructor and a Final Field

Let’s start by adding the element names.

We’ll set the names into a final variable using a constructor:

First of all, we notice the special syntax in the declaration list. This is how a constructor is invoked for enum types. Although it’s illegal to use the new operator for an enum, we can pass constructor arguments in the declaration list.

We then declare an instance variable label. There are a few things to note about that.

First, we chose the label identifier instead of the name. Although the member field name is available to use, let’s choose label to avoid confusion with the predefined Enum.name() method.

Second, our label field is final. While fields of an enum do not have to be final, in most cases we don’t want our labels to change. In the spirit of enum values being constant, this makes sense.

Finally, the label field is public, so we can access the label directly:

On the other hand, the field can be private, accessed with a getLabel() method. For the purpose of brevity, this article will continue to use the public field style.

4. Locating Java Enum Values

Java provides a valueOf(String) method for all enum types.

Thus, we can always get an enum value based on the declared name:

assertSame(Element.LI, Element.valueOf("LI"));

However, we may want to look up an enum value by our label field as well.

To do that, we can add a static method:

public static Element valueOfLabel(String label) < for (Element e : values()) < if (e.label.equals(label)) < return e; >> return null; >

The static valueOfLabel() method iterates the Element values until it finds a match. It returns null if no match is found. Conversely, an exception could be thrown instead of returning null.

Let’s see a quick example using our valueOfLabel() method:

assertSame(Element.LI, Element.valueOfLabel("Lithium"));

5. Caching the Lookup Values

We can avoid iterating the enum values by using a Map to cache the labels.

To do this, we define a static final Map and populate it when the class loads:

public enum Element < // . enum values private static final MapBY_LABEL = new HashMap<>(); static < for (Element e: values()) < BY_LABEL.put(e.label, e); >> // . fields, constructor, methods public static Element valueOfLabel(String label) < return BY_LABEL.get(label); >>

As a result of being cached, the enum values are iterated only once, and the valueOfLabel() method is simplified.

As an alternative, we can lazily construct the cache when it is first accessed in the valueOfLabel() method. In that case, map access must be synchronized to prevent concurrency problems.

6. Attaching Multiple Values

The Enum constructor can accept multiple values.

To illustrate, let’s add the atomic number as an int and the atomic weight as a float:

public enum Element < H("Hydrogen", 1, 1.008f), HE("Helium", 2, 4.0026f), // . NE("Neon", 10, 20.180f); private static final MapBY_LABEL = new HashMap<>(); private static final Map BY_ATOMIC_NUMBER = new HashMap<>(); private static final Map BY_ATOMIC_WEIGHT = new HashMap<>(); static < for (Element e : values()) < BY_LABEL.put(e.label, e); BY_ATOMIC_NUMBER.put(e.atomicNumber, e); BY_ATOMIC_WEIGHT.put(e.atomicWeight, e); >> public final String label; public final int atomicNumber; public final float atomicWeight; private Element(String label, int atomicNumber, float atomicWeight) < this.label = label; this.atomicNumber = atomicNumber; this.atomicWeight = atomicWeight; >public static Element valueOfLabel(String label) < return BY_LABEL.get(label); >public static Element valueOfAtomicNumber(int number) < return BY_ATOMIC_NUMBER.get(number); >public static Element valueOfAtomicWeight(float weight) < return BY_ATOMIC_WEIGHT.get(weight); >>

Similarly, we can add any values we want to the enum, such as the proper case symbols, “He”, “Li” and “Be”, for example.

Moreover, we can add computed values to our enum by adding methods to perform operations.

7. Controlling the Interface

As a result of adding fields and methods to our enum, we’ve changed its public interface. Therefore our code, which uses the core Enum name() and valueOf() methods, will be unaware of our new fields.

The static valueOf() method is already defined for us by the Java language, so we can’t provide our own valueOf() implementation.

Similarly, because the Enum.name() method is final, we can’t override it either.

As a result, there’s no practical way to utilize our extra fields using the standard Enum API. Instead, let’s look at some different ways to expose our fields.

7.1. Overriding toString()

Overriding toString() may be an alternative to overriding name():

@Override public String toString()

By default, Enum.toString() returns the same value as Enum.name().

7.2. Implementing an Interface

The enum type in Java can implement interfaces. While this approach is not as generic as the Enum API, interfaces do help us generalize.

Let’s consider this interface:

For consistency with the Enum.name() method, our label() method does not have a get prefix.

And because the valueOfLabel() method is static, we do not include it in our interface.

Finally, we can implement the interface in our enum:

public enum Element implements Labeled < // . @Override public String label() < return label; >// . >

One benefit of this approach is that the Labeled interface can be applied to any class, not just enum types. Instead of relying on the generic Enum API, we now have a more context-specific API.

8. Conclusion

In this article, we’ve explored many features of the Java Enum implementation. By adding constructors, fields and methods, we see that the enum can do a lot more than literal constants.

As always, the full source code for this article can be found over on GitHub.

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

Источник

Читайте также:  Html шаблон для свадьбы
Оцените статью