В "Java Programming Ideas" есть такая фраза: "Иногда именно благодаря ей можно решать задачи "элегантно и чисто"" - о ком идет речь в этой фразе? Именно главному герою этой статьи — перечислению (Enum) — все аплодируют.
Задолго до того,яПеречислениями особо не пользуюсь, потому что всегда чувствую, что это бесполезно - это собственно и есть недальновидность "самопознания".Когда человек сидит на корточках в своем глубоком колодце и не решается выпрыгнуть, то он действительно может видеть только небо размером с устье колодца..
Шло время, я работал над все большим количеством проектов и имел все больше и больше возможностей познакомиться с перечислением, поэтому постепенно я все больше и больше интересовался им, и после долгих исследований я обнаружил, что исходное перечисление настолько превосходно.
1) Общее использование перечисления
Сжатое перечисление очень чистое и элегантное, см. пример ниже.
public enum Chenmo {
WANGER, WANGSAN, WANGSI
}
Мы создали три значения для перечисления тишины, а именно король два, король три и король четыре. Этот код на самом деле вызывается 3 разаEnum(String name, int ordinal)
(Слово ординал означает порядок), то есть:
new Enum<Chenmo>("WANGER", 0);
new Enum<Chenmo>("WANGSAN", 1);
new Enum<Chenmo>("WANGSI", 2);
Перейдем и выведем перечисление:
for (Chenmo e : Chenmo.values()) {
System.out.println(e);
}
//输出
//WANGER
//WANGSAN
//WANGSI
2) Как условие переключения
Использование перечисления в качестве условия для оператора switch может сделать наш код более читабельным, как показано в следующем примере.
Chenmo key = Chenmo.WANGER;
switch (key) {
case WANGSI:
System.out.println("今天我送出一个CSDN大鼠标垫");
break;
case WANGSAN:
System.out.println("今天我被坑一个CSDN学院年卡");
break;
default:
System.out.println("今天我一边高兴,一边失落");
break;
}
Судя по ключевому слову case, вы можете напрямую использовать значение перечисления, что очень лаконично. Кроме того, определение типа во время компиляции может эффективно избежать ситуации выхода за границы — тип строковой константы легко может оказаться за пределами границ из-за неправильного написания, когда он используется в качестве условия оценки переключения.
3) Перечисление реализует синглтон
Книга «Эффективная Java» восхваляет использование перечислений для реализации синглетонов:
Метод реализации синглетонов с помощью перечислений не получил широкого распространения, но одноэлементные типы перечисления стали лучшим способом реализации синглтонов.
Я думаю, что слова «хотя еще не получили широкого распространения» можно убрать, ведь теперь все должны знать, что использование перечислений для реализации синглетонов — очень хороший способ.
Давайте сначала посмотрим на синглтон, реализованный с помощью «блокировки с двойной проверкой»:
public class SingleTon2 {
// 私有化构造方法
private SingleTon2() {
};
private static volatile SingleTon2 singleTon = null;
public static SingleTon2 getInstance() {
// 第一次校验
if (singleTon == null) {
synchronized (SingleTon2.class) {
// 第二次校验
if (singleTon == null) {
singleTon = new SingleTon2();
}
}
}
return singleTon;
}
}
Давайте посмотрим на синглтон реализации перечисления:
public enum SingleTon {
INSTANCE;
public void method() {
System.out.println("我很快乐!");
}
}
Если вы не знаете, вы будете в шоке! Синглтон перечисления ужасно прост — я добавил метод, который печатает «Я счастлив», чтобы это не выглядело слишком упрощенно.
Реализованные перечислением синглтоны легко решают две проблемы:
①, вопросы безопасности потоков. Поскольку виртуальная машина Java будет использовать метод loadClass объекта ClassLoader при загрузке класса перечисления, этот метод использует блок синхронизированного кода для обеспечения безопасности потоков.
2. Избегайте десериализации из-за уничтожения синглетонов. Потому что десериализация перечислений не достигается отражением.
4) Перечисление может взаимодействовать с базой данных
Мы можем преобразовать поля базы данных в типы перечисления с помощью Mybatis. Теперь предположим, что в базе данных есть поле check_type следующего типа:
`check_type` int(1) DEFAULT NULL COMMENT '检查类型(1:未通过、2:通过)',
Соответствующий ему тип перечисления — CheckType, а код выглядит следующим образом:
public enum CheckType {
NO_PASS(0, "未通过"), PASS(1, "通过");
private int key;
private String text;
private CheckType(int key, String text) {
this.key = key;
this.text = text;
}
public int getKey() {
return key;
}
public String getText() {
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;
}
}
Класс перечисления CheckType немного сложнее, чем класс перечисления Chenmo, который мы только что видели.
Во-первых, в CheckType появился новый метод построения, и есть два поля, ключ типа int и текст типа String.
Во-вторых, есть CheckTypepublic static CheckType parse(Integer index)
метод, который может преобразовать Integer в тип перечисления посредством сопоставления ключей.
Итак, теперь мы можем использовать в файле конфигурации MybatistypeHandler
Преобразование полей базы данных в типы перечисления.
<resultMap id="CheckLog" type="com.entity.CheckLog">
<id property="id" column="id"/>
<result property="checkType" column="check_type" typeHandler="com.CheckTypeHandler"></result>
</resultMap>
Класс, соответствующий полю checkType, выглядит следующим образом:
public class CheckLog implements Serializable {
private String id;
private CheckType checkType;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public CheckType getCheckType() {
return checkType;
}
public void setCheckType(CheckType checkType) {
this.checkType = checkType;
}
}
Исходный код класса преобразователя CheckTypeHandler выглядит следующим образом:
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());
}
}
Основной функцией CheckTypeHandler является вызов класса перечисления CheckType.parse()
метод преобразования полей базы данных.
5) Будут ли перечисления потреблять больше памяти, чем статические константы?
После разговора о 4 наиболее часто используемых знаниях о перечислении давайте обсудим тему «Будет ли перечисление потреблять больше памяти, чем статические константы?» — кто-то задал этот вопрос на Zhihu, и многие люди участвовали в ответе.
Насколько я понимаю, человек, задающий этот вопрос, кажется, спрашивает, «0,000,001» больше, чем «0,000,000,99»? Вы согласны?
Предыдущий:Если кто-то снова спросит вас об отражении в Java, киньте ему эту статью
Следующий:Аннотация Java: Пожалуйста, не недооценивайте меня!
Поиск в WeChat »Тихий король 2"Общественный номер, подпишитесь и ответьте"бесплатное видео"Получите 500 ГБ высококачественных обучающих видео (по категориям).