To cut to the quick, enum is a keyword introduced in Java 1.5 that represents a special type of class that inherits by default from java.lang.enum.
To prove this, let’s create a new enumerated PlayerType:
public enum PlayerType {
TENNIS,
FOOTBALL,
BASKETBALL
}
Copy the code
Two keywords with a class name, curly braces, and three uppercase words. Don’t worry. A watched pot never boils. A look at the decompiled bytecode using JAD makes it crystal clear.
public final class PlayerType extends Enum
{
public static PlayerType[] values()
{
return (PlayerType[])$VALUES.clone();
}
public static PlayerType valueOf(String name)
{
return (PlayerType)Enum.valueOf(com/cmower/baeldung/enum1/PlayerType, name);
}
private PlayerType(String s, int i)
{
super(s, i);
}
public static final PlayerType TENNIS;
public static final PlayerType FOOTBALL;
public static final PlayerType BASKETBALL;
private static final PlayerType $VALUES[];
static
{
TENNIS = new PlayerType("TENNIS".0);
FOOTBALL = new PlayerType("FOOTBALL".1);
BASKETBALL = new PlayerType("BASKETBALL".2);
$VALUES = (newPlayerType[] { TENNIS, FOOTBALL, BASKETBALL }); }}Copy the code
See yet? The PlayerType class is final and inherits from the Enum class. We programmers don’t do this work, the compiler does it for us quietly. In addition, it comes with several useful static methods, such as values() and valueOf(String name).
01, internal enumeration
Okay, so you guys already know what enumerations look like? Since enumeration is a special class, it can be defined inside a class so that its scope can be restricted to the external class.
public class Player {
private PlayerType type;
public enum PlayerType {
TENNIS,
FOOTBALL,
BASKETBALL
}
public boolean isBasketballPlayer(a) {
return getType() == PlayerType.BASKETBALL;
}
public PlayerType getType(a) {
return type;
}
public void setType(PlayerType type) {
this.type = type; }}Copy the code
PlayerType is the equivalent of a Player’s inner class, and the isBasketballPlayer() method is used to determine if a Player is a basketball Player.
Since enumerations are final, ensuring that there is only one constant object in the Java virtual machine (see the decomcompiled static block “static keyword with curly braces”), we can safely use the “==” operator to compare two enumerations for equality. See isBasketballPlayer().
So why not use equals()?
if(player.getType().equals(Player.PlayerType.BASKETBALL)){};
if(player.getType() == Player.PlayerType.BASKETBALL){};
Copy the code
When the “==” operator compares two objects that are both null, NullPointerException does not occur, as does equals().
In addition, the “==” operator checks at compile time and gives an error if the types on both sides do not match, whereas the equals() method does not.
02. Enumeration can be used in switch statements
I explained this in detail in my previous article. If you are interested, you can click the link to jump to the past and have a look.
switch (playerType) {
case TENNIS:
return "Federer the Tennis player.";
case FOOTBALL:
return "Cristiano Ronaldo, soccer player.";
case BASKETBALL:
return "James the Basketball Player";
case UNKNOWN:
throw new IllegalArgumentException("Unknown");
default:
throw new IllegalArgumentException(
"Type of athlete:" + playerType);
}
Copy the code
Enumerations can have constructors
If the enumeration needs to contain more information, you can add fields to it, such as Name in the following example. In this case, you need to add a constructor with parameters to the enumeration so that the corresponding name can be added when the enumeration is defined.
public enum PlayerType {
TENNIS("Tennis"),
FOOTBALL("Football"),
BASKETBALL("Basketball");
private String name;
PlayerType(String name) {
this.name = name; }}Copy the code
04, enumsets
EnumSet is an implementation class for the Set interface for enumeration types. It is a very efficient tool for handling enumeration data (the internal implementation is bit vectors, which I don’t understand).
Because EnumSet is an abstract class, you cannot use the new keyword when creating EnumSet. However, EnumSet provides a number of useful static factory methods:
The following example uses noneOf() to create an empty EnumSet of PlayerType; Use allOf() to create an EnumSet containing all playerTypes.
public class EnumSetTest {
public enum PlayerType {
TENNIS,
FOOTBALL,
BASKETBALL
}
public static void main(String[] args) { EnumSet<PlayerType> enumSetNone = EnumSet.noneOf(PlayerType.class); System.out.println(enumSetNone); EnumSet<PlayerType> enumSetAll = EnumSet.allOf(PlayerType.class); System.out.println(enumSetAll); }}Copy the code
The program output is as follows:
[]
[TENNIS, FOOTBALL, BASKETBALL]
Copy the code
With EnumSet in place, we can use some of the methods of Set:
05, EnumMap
EnumMap is an implementation class for the Map interface for enumeration types that can use enumeration constants as keys. EnumMap is even more efficient than HashMap, and elements can be accessed directly by array subscript (ordinal value of enumeration).
Unlike EnumSet, EnumMap is not an abstract class, so the new keyword can be used to create EnumMap:
EnumMap<PlayerType, String> enumMap = new EnumMap<>(PlayerType.class);
Copy the code
Once you have the EnumMap object, you can use some of the Map methods:
In much the same way as using HashMap, consider the following example:
EnumMap<PlayerType, String> enumMap = new EnumMap<>(PlayerType.class);
enumMap.put(PlayerType.BASKETBALL,"Basketball player");
enumMap.put(PlayerType.FOOTBALL,"Football player.");
enumMap.put(PlayerType.TENNIS,"Tennis player.");
System.out.println(enumMap);
System.out.println(enumMap.get(PlayerType.BASKETBALL));
System.out.println(enumMap.containsKey(PlayerType.BASKETBALL));
System.out.println(enumMap.remove(PlayerType.BASKETBALL));
Copy the code
The program output is as follows:
{TENNIS= TENNIS player, FOOTBALL= FOOTBALL player, BASKETBALL= BASKETBALL playertrueBasketball playerCopy the code
06, singleton
In general, implementing a singleton is not an easy task. Take a look at this code
public class Singleton {
private volatile static Singleton singleton;
private Singleton (a){}
public static Singleton getSingleton(a) {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}}returnsingleton; }}Copy the code
But enumerations reduce the code to the extreme:
public enum EasySingleton{
INSTANCE;
}
Copy the code
We’re done. It was super short, wasn’t it? Enumeration implements the Serializable interface by default, so the Java VIRTUAL machine can guarantee that the class is a singleton, unlike the traditional implementation. Traditionally, we had to ensure that singletons could not create any new instances during deserialization.
07. Enumerations interact with databases
We can work with Mybatis to convert database fields to enumerated types. Now suppose we have a database field check_type of the following type:
`check_type` int(1) DEFAULT NULL COMMENT 'Check type (1: failed, 2: passed)'.Copy the code
Its corresponding enumeration type is CheckType and the code is as follows:
public enum CheckType {
NO_PASS(0."Failed"), PASS(1."通过");
private int key;
private String text;
private CheckType(int key, String text) {
this.key = key;
this.text = text;
}
public int getKey(a) {
return key;
}
public String getText(a) {
return text;
}
private static HashMap<Integer,CheckType> map = new HashMap<Integer,CheckType>();
static {
for(CheckType d : CheckType.values()){ map.put(d.key, d); }}public static CheckType parse(Integer index) {
if(map.containsKey(index)){
return map.get(index);
}
return null; }}Copy the code
Select * from CheckType where key = int and text = String;
CheckType parse(Integer index) public static CheckType parse(Integer index) converts an Integer to an enumerated type by matching the key.
So now we can use typeHandler in the Mybatis configuration file to convert database fields to enumerated types.
<resultMap id="CheckLog" type="com.entity.CheckLog">
<id property="id" column="id"/>
<result property="checkType" column="check_type" typeHandler="com.CheckTypeHandler"></result>
</resultMap>
Copy the code
The class corresponding to the checkType field is as follows:
public class CheckLog implements Serializable {
private String id;
private CheckType checkType;
public String getId(a) {
return id;
}
public void setId(String id) {
this.id = id;
}
public CheckType getCheckType(a) {
return checkType;
}
public void setCheckType(CheckType checkType) {
this.checkType = checkType; }}Copy the code
The CheckTypeHandler converter class source code is as follows:
public class CheckTypeHandler extends BaseTypeHandler<CheckType> {
@Override
public CheckType getNullableResult(ResultSet rs, String index) throws SQLException {
return CheckType.parse(rs.getInt(index));
}
@Override
public CheckType getNullableResult(ResultSet rs, int index) throws SQLException {
return CheckType.parse(rs.getInt(index));
}
@Override
public CheckType getNullableResult(CallableStatement cs, int index) throws SQLException {
return CheckType.parse(cs.getInt(index));
}
@Override
public void setNonNullParameter(PreparedStatement ps, int index, CheckType val, JdbcType arg3) throws SQLException { ps.setInt(index, val.getKey()); }}Copy the code
The core function of CheckTypeHandler is to convert database fields by calling the Parse () method of the CheckType enumeration class.
To tell you the truth, after reading this article, I think friends will definitely use Java enumeration, if not, come to chop me!
If you feel that the article is helpful to you, please search wechat “Silent King ii” for the first time to read, reply to “concurrency” there is a rewrite of Ali Daniel Java concurrent programming actual combat, from now on no longer need to worry about the interviewer in this aspect of difficulties.
GitHub, portal ~, GitHub, portal ~, GitHub, Portal ~
I am the Silent King 2, a programmer with good looks but mediocre talent. Attention can improve learning efficiency, don’t forget three even ah, like, collect, message, I don’t pick, hee hee.