предисловие
Текст был включен в мой репозиторий GitHub, добро пожаловать, звезда:GitHub.com/bin39232820…
Лучшее время для посадки дерева было десять лет назад, затем сейчас
Я знаю, что многие люди не играютqqТеперь, но с ностальгией, добро пожаловать в группу Six Meridian Excalibur по изучению Java для новичков, номер группового чата:549684836Поощряйте всех вести блог на пути к технологиям
болтовня
Я только вчера столкнулся с небольшой проблемой с перечислением, а потом обнаружил, что я не так знаком с этим, а потом в разработке много используется перечисление, поэтому у меня есть сегодняшняя статья.
что такое перечисление
Перечисление в Java — это тип, как следует из названия: он перечисляется один за другим. Таким образом, он обычно представляет тип с ограниченным набором, который является типом, и определение, данное в Википедии, таково:
В математике и теории информатики перечисление набора — это программа, которая перечисляет все элементы некоторого конечного набора последовательностей или количество объектов определенного типа. Эти два типа часто (но не всегда) пересекаются. Перечисление представляет собой набор именованных целочисленных констант. Перечисления очень распространены в повседневной жизни. Например, ВОСКРЕСЕНЬЕ, ПОНЕДЕЛЬНИК, ВТОРНИК, СРЕДА, ЧЕТВЕРГ, ПЯТНИЦА, СУББОТА, представляющие неделю, являются перечислением.
Причина появления
До Java5 перечисления фактически не было, поэтому давайте посмотрим, как решить сценарий использования перечисления до Java5? Здесь я вижу часть дизайна для перечислений до Java 1.4:
public class Season {
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
}
Этот метод называется режимом перечисления. Но что не так с этим шаблоном?Обычно мы пишем код с учетом его безопасности, простоты использования и удобочитаемости. Сначала давайте рассмотрим его типобезопасность. Конечно, этот шаблон не является типобезопасным. Например, мы разрабатываем функцию, которая требует передачи определенного значения весны, лета, осени и зимы. Но с типом int мы не можем гарантировать, что переданное значение является допустимым. Код выглядит следующим образом:
private String getChineseSeason(int season){
StringBuffer result = new StringBuffer();
switch(season){
case Season.SPRING :
result.append("春天");
break;
case Season.SUMMER :
result.append("夏天");
break;
case Season.AUTUMN :
result.append("秋天");
break;
case Season.WINTER :
result.append("冬天");
break;
default :
result.append("地球没有的季节");
break;
}
return result.toString();
}
Потому что, когда мы передаем значения, мы можем передавать другие типы, что может привести к дефолту, так что это не решает проблему безопасности типов в источнике.
Далее мы рассмотрим читаемость этого шаблона. В большинстве случаев, когда я использую перечисления, мне нужно легко получить строковое выражение типа перечисления. Если мы распечатаем константу int enum, все, что мы увидим, — это набор чисел, что не очень полезно. Мы могли бы подумать об использовании констант String вместо констант int. Хотя он предоставляет печатные строки для этих констант, он может вызвать проблемы с производительностью, поскольку он основан на операциях сравнения строк, поэтому этот шаблон также не ожидается. С точки зрения безопасности типов и читабельности программы выявлены недостатки паттернов перечисления int и String. К счастью, после выпуска Java 1.5 было предложено альтернативное решение, которое позволяет избежать недостатков шаблонов перечисления int и String и обеспечивает множество дополнительных преимуществ. Это тип перечисления.
определение перечисления
Тип перечисления — это допустимый тип, состоящий из фиксированного набора констант. Тип перечисления определяется в Java ключевым словом enum. Ниже приведено определение типа перечисления java.
public enum Season {
SPRING, SUMMER, AUTUMN, WINER;
}
Заявление Java об определении типа перечисления очень лаконично. Он имеет следующие особенности:
- Используйте ключевое слово enum
- Введите здесь название, например «Сезон».
- Строка допустимых значений, таких как четыре сезона, определенные выше для весны, лета, осени и зимы.
- Перечисления могут быть определены отдельно в файле или встроены в другие классы Java.
- Перечисление может реализовывать один или несколько интерфейсов (Interface).
- Могут быть определены новые переменные и методы
Перепишите приведенный выше метод перечисления
Ниже приведен очень канонический тип перечисления.
public enum Season {
SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
private int code;
private Season(int code){
this.code = code;
}
public int getCode(){
return code;
}
}
public class UseSeason {
/**
* 将英文的季节转换成中文季节
* @param season
* @return
*/
public String getChineseSeason(Season season){
StringBuffer result = new StringBuffer();
switch(season){
case SPRING :
result.append("[中文:春天,枚举常量:" + season.name() + ",数据:" + season.getCode() + "]");
break;
case AUTUMN :
result.append("[中文:秋天,枚举常量:" + season.name() + ",数据:" + season.getCode() + "]");
break;
case SUMMER :
result.append("[中文:夏天,枚举常量:" + season.name() + ",数据:" + season.getCode() + "]");
break;
case WINTER :
result.append("[中文:冬天,枚举常量:" + season.name() + ",数据:" + season.getCode() + "]");
break;
default :
result.append("地球没有的季节 " + season.name());
break;
}
return result.toString();
}
public void doSomething(){
for(Season s : Season.values()){
System.out.println(getChineseSeason(s));//这是正常的场景
}
//System.out.println(getChineseSeason(5));
//此处已经是编译不通过了,这就保证了类型安全
}
public static void main(String[] arg){
UseSeason useSeason = new UseSeason();
useSeason.doSomething();
}
}
Общие методы класса Enum
имя метода | описывать |
---|---|
values() | Возвращает все члены типа перечисления в виде массива |
valueOf() | Преобразовать обычную строку в экземпляр enum |
compareTo() | Сравните порядок, в котором определены два члена перечисления |
ordinal() | Получить позицию индекса члена перечисления |
метод значения()
Все члены перечисления можно вернуть в виде массива, вызвав метод values() экземпляра перечисляемого типа, и с помощью этого метода также можно получить члены перечисляемого типа.
В следующем примере создается тип перечисления Signal с 3 элементами, а затем вызывается метод values() для вывода членов.
public enum Signal {
//定义一个枚举类型
GREEN,YELLOW,RED;
public static void main(String[] args)
{
for(int i=0;i<Signal.values().length;i++)
{
System.out.println("枚举成员:"+Signal.values()[i]);
}
}
}
результат
//枚举成员:GREEN
//枚举成员:YELLOW
//枚举成员:RED
метод valueOf
Получить один объект enum по строке
public enum Signal {
//定义一个枚举类型
GREEN,YELLOW,RED;
public static void main(String[] args)
{
Signal green = Signal.valueOf("GREEN");
System.out.println(green);
}
}
результат
//GREEN
порядковый() метод
Позицию индекса члена в перечислении можно получить, вызвав метод ordinal() экземпляра типа перечисления. В следующем примере создается тип перечисления Signal с 3 элементами, а затем вызывается метод ordinal() для вывода элементов и соответствующих им позиций индекса.
public class TestEnum1
{
enum Signal
{
//定义一个枚举类型
GREEN,YELLOW,RED;
}
public static void main(String[] args)
{
for(int i=0;i<Signal.values().length;i++)
{
System.out.println("索引"+Signal.values()[i].ordinal()+",值:"+Signal.values()[i]);
}
}
}
результат
//索引0,值:GREEN
//索引1,值:YELLOW
//索引2,值:RED
Перечисление реализует синглтон
Метод реализации синглетонов с помощью перечислений не получил широкого распространения, но одноэлементные типы перечисления стали лучшим способом реализации синглтонов.
Голодный китайский стиль синглтона
package com.atguigu.ct.producer.controller;
//final 不允许被继承
public final class HungerSingleton {
private static HungerSingleton instance=new HungerSingleton();
//私有构造函数不允许外部new
private HungerSingleton(){
}
//提供一个方法给外部调用
public static HungerSingleton getInstance(){
return instance;
}
}
ленивый синглтон
package com.atguigu.ct.producer.controller;
//final 不能被继承
public final class DoubleCheckedSingleton {
//定义实例但是不直接初始化,volatile禁止重排序操作,避免空指针异常
private static DoubleCheckedSingleton instance=new DoubleCheckedSingleton();
//私有构造函数不允许外部new
private DoubleCheckedSingleton(){
}
//对外提供的方法用来获取单例对象
public static DoubleCheckedSingleton getInstance(){
if(null==instance){
synchronized (DoubleCheckedSingleton.class){
if (null==instance) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
пронумерованный синглтон
package com.atguigu.ct.producer.controller;
public enum EnumSingleton {
//定义一个单例对象
INSTANCE;
//获取单例对象的方法
public static EnumSingleton getInstance(){
return INSTANCE;
}
}
В другом классе, для которого требуется синглтон, определите статический класс перечисления для реализации одноэлементного перечисления.
Глядя на три приведенных выше метода, вы можете видеть, что режим синглтона является самым простым, просто взглянув на код.Поскольку сам синглтон создается частным образом, рекомендуется использовать перечисление для реализации синглетонов в будущем.
вопросы интервью
Разрешено ли перечислениям наследовать классы?
Перечисления не позволяют наследовать классы. JVM унаследовала класс Enum при генерации перечисления.Поскольку язык Java является одиночным наследованием, он не поддерживает наследование дополнительных классов (единственная квота наследования используется JVM).
Можно ли сравнивать перечисления по знаку равенства?
Перечисления можно сравнивать с помощью знака равенства. JVM будет генерировать объект класса, соответствующий каждому экземпляру перечисления.Этот объект класса украшен общедоступным статическим финалом, инициализируется в статическом блоке кода и является синглтоном.
Может ли перечисление быть унаследовано другими?
Перечисления не могут наследоваться. Потому что JVM объявляет его окончательным, когда генерирует класс enum.
конец
На самом деле перечислений очень много. Если вы определяете константы, использование перечислений действительно намного элегантнее. Не забывайте использовать их чаще в своих проектах.
ежедневные комплименты
Хорошо всем, вышеизложенное является полным содержанием этой статьи. Люди, которые могут видеть это здесь, всенастоящий порошок.
Творить нелегко. Ваша поддержка и признание — самая большая мотивация для моего творчества. Увидимся в следующей статье.
Six Meridians Excalibur | Text [Original] Если в этом блоге есть какие-то ошибки, прошу покритиковать и посоветовать, буду очень признателен!