RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 559045
Accepted
SweetDev
SweetDev
Asked:2020-08-25 00:52:39 +0000 UTC2020-08-25 00:52:39 +0000 UTC 2020-08-25 00:52:39 +0000 UTC

枚举的实际使用

  • 772

我一直关心类问题Enum:它们比普通static final原语有什么优势?

并且,如果可能的话,分享您的使用Enum真正合理的经验。

java
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Best Answer
    Volen
    2020-08-25T01:30:36Z2020-08-25T01:30:36Z

    enum与 .相比,使用时具有许多优点static final int。如果您需要这些好处,那么值得使用它。

    主要区别在于使用enum您可以检查数据类型。

    例如:

    public class SomeClass {
        public static int RED = 1;
        public static int BLUE = 2;
        public static int YELLOW = 3;
        public static int GREEN = 3; // Совпадающие значения
    
        private int color;
    
        public void setColor(int color) {
            this.color = color;
        }   
    }
    

    但是,您可以将任何值传递给类int。

    new SomeClass().setColor(999);
    

    因此,使用中存在的主要问题static final int是:

    • 需要验证输入数据。
    • 无法防止创建static final int具有重复值的变量。

    另一个优点enum是能够重载方法。

    public enum UnitConverter{
        METERS{
            @Override
            public double toMiles(final double meters){
                return meters * 0.00062137D;
            }
    
            @Override
            public double toMeters(final double meters){
                return meters;
            }
        },
        MILES{
            @Override
            public double toMiles(final double miles){
                return miles;
            }
    
            @Override
            public double toMeters(final double miles){
                return miles / 0.00062137D;
            }
        };
    
        public abstract double toMiles(double unit);
        public abstract double toMeters(double unit);
    }
    

    使用的缺点enum

    • 运算符 >、<、>=、<= 不适用于它们。因此enum,它不应该用在顺序数据列表中。
    • enum还需要比常规常量更多的内存来存储。

    IntDefStringDef在安卓系统中

    Google不建议在 Android 应用程序中使用enum,因为它需要更多内存。相反,对于 Android,您可以使用IntDefandStringDef来限制常规常量的值空间。因此,您可以获得enum不浪费内存使用量的主要好处。这种做法在标准的 Android 类中无处不在:

    /** @hide */
    @IntDef({VISIBLE, INVISIBLE, GONE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Visibility {}
    
    /**
     * This view is visible.
     * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
     * android:visibility}.
     */
    public static final int VISIBLE = 0x00000000;
    
    /**
     * This view is invisible, but it still takes up space for layout purposes.
     * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
     * android:visibility}.
     */
    public static final int INVISIBLE = 0x00000004;
    
    /**
     * This view is invisible, and it doesn't take any space for layout
     * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
     * android:visibility}.
     */
    public static final int GONE = 0x00000008;  
    

    接收方法使用了一个特殊的注解:

    public void setVisibility(@Visibility int visibility) {
        setFlags(visibility, VISIBILITY_MASK);
        if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
    } 
    

    在这种情况下,您将无法为此方法使用另一个常量:

    view.setVisibility(456);//Error: Must be one of: View.VISIBLE, View.INVISIBLE, View.GONE
    
    • 27
  2. Артём Ионаш
    2020-08-25T01:44:40Z2020-08-25T01:44:40Z

    枚举( Enum) 可以方便地用于表示一组互斥状态。

    消息代码枚举示例:

    enum MessageCode
    {
        // Установка однозначного соответствия 
        // между элементом перечисления и целочисленным значением.
        UNKNOWN(0),
    
        TOAST(1),
        MESSAGE(2);
    
        private final int id;
    
        MessageCode(int code)
        {
            id = code;
        }
    
        // Метод получения целочисленного значения,
        // соответствующего выбранному элементу Перечисления (Enum)
        public int getId()
        {
            return id;
        }
    
        // Метод получения элемента Перечисления (Enum),
        // соответствующего переданному целочисленному значению
        public static MessageCode fromId(int code)
        {
            MessageCode[] list = MessageCode.values();
    
            if (code >= 0 && code < list.length)
                return list[code];
            else
                return MessageCode.UNKNOWN;
        }
    }
    

    消息解析示例:

    private Messenger chatUIThreadMessenger = new Messenger(new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            String str;
            switch (MessageCode.fromId(msg.what))
            {
            // Доступ к выводу Toast'ов для Thread'ов прослушивающих Socket'ы
            case TOAST:
                str = (String) msg.obj;
                Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
                break;
            // Вывод сообщений в лог чата
            case MESSAGE:
                str = (String) msg.obj;
                messages.add(str);
                messagesAdapter.notifyDataSetChanged();
                final ListView listView = (ListView) findViewById(R.id.listViewChat);
                listView.smoothScrollToPosition(messagesAdapter.getCount() - 1);
                break;
            // Исключительная ситуация
            case UNKNOWN:
                Toast.makeText(getBaseContext(),
                    "Messenger: неопределённый тип сообщения!", Toast.LENGTH_LONG).show();
                break;
            default:
                super.handleMessage(msg);
            }
        }
    });
    
    • 12
  3. ЮрийСПб
    2020-08-25T01:26:21Z2020-08-25T01:26:21Z

    使用enuminstead of constants 很有用,例如,当您想限制方法参数的可能值集时。如果您使用常量(例如intor String),并且应该接受它的方法将具有相应的参数类型,那么没有什么可以阻止您在那里传递常量之外的东西。如果您使用enum,那么您将无法传输enum除 .

    • 10
  4. Denis Vabishchevich
    2020-01-09T19:19:42Z2020-01-09T19:19:42Z

    Enum可以用作单例模式的实现。

    好处:

    1. 开箱即用的序列化
    2. 开箱即用的线程安全
    3. 能够使用 EnumSet、EnumMap 等
    4. 切换支持

    瑕疵

    1. 非惰性初始化

    根据Joshua Bloch的说法,这是实现该模式的最佳方式

    public enum Singleton {
        INSTANCE;
    }
    
    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5