Câu hỏi Tại sao Android không sử dụng nhiều enums hơn?


Tôi đã bắt đầu thực sự thích sử dụng C # và Java enums trong mã của tôi vì nhiều lý do:

  • Chúng an toàn hơn nhiều so với các số nguyên, chuỗi hoặc các bộ cờ boolean.
  • Chúng dẫn đến mã dễ đọc hơn.
  • Khó đặt một enum thành giá trị không hợp lệ hơn là int hoặc chuỗi.
  • Chúng giúp bạn dễ dàng khám phá các giá trị được phép cho một biến hoặc tham số.
  • Tất cả những gì tôi đã đọc chỉ ra rằng chúng thực hiện cũng như các số nguyên trong C # và hầu hết các JVM.

Tuy nhiên, khung công tác Android có nhiều trường hợp mà các cờ của nhiều loại khác nhau cần phải được truyền đi, nhưng không ai trong số chúng có vẻ sử dụng enums. Một vài ví dụ mà tôi nghĩ rằng việc sử dụng chúng sẽ mang lại lợi ích Toast.LENGTH_SHORT / Toast.LENGTH_LONG và View.GONE, View.VISIBLE, v.v.

Tại sao điều này? Do enums thực hiện tồi tệ hơn so với giá trị số nguyên đơn giản trong Dalvik? Có một số nhược điểm khác mà tôi không biết?


76
2018-01-27 22:49


gốc


Bây giờ là ok để sử dụng enum. Xem stackoverflow.com/questions/5143256/… - Thierry-Dimitri Roy
Tuyệt quá! Tôi thích enums và tôi đã không nhận được xung quanh để đưa chúng ra được nêu ra. - jnylen


Các câu trả lời:


Câu trả lời này đã lỗi thời kể từ tháng 3 năm 2011. 

Enums có thể được sử dụng trên Froyo và lên - theo câu trả lời này (Tại sao "Tránh Enums nơi bạn chỉ cần Ints" loại bỏ từ lời khuyên hiệu suất của Android?) từ một thành viên của nhóm Android VM (và blog của anh ấy).


Câu trả lời trước:

Đề xuất nhóm Android chính thức là để tránh enums bất cứ khi nào bạn có thể tránh nó:

Enums rất tiện lợi, nhưng   không may có thể gây đau khi kích thước   và tốc độ vật chất. Ví dụ, điều này:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

thêm 740 byte vào   tệp .dex của bạn so với   lớp tương đương với ba công chúng   static ints cuối cùng. Khi sử dụng lần đầu,   class initializer gọi ra   phương pháp trên các đối tượng đại diện cho từng   các giá trị được liệt kê. Mỗi đối tượng   có trường tĩnh của riêng nó và   tập hợp đầy đủ được lưu trữ trong một mảng (một   trường tĩnh được gọi là "$ VALUES"). Đó là   rất nhiều mã và dữ liệu, chỉ dành cho ba   số nguyên. Ngoài ra, điều này:

Shrubbery shrub = Shrubbery.GROUND;

gây tra cứu trường tĩnh. Nếu   "GROUND" là một int cuối cùng tĩnh,   trình biên dịch sẽ coi nó như một   liên tục và nội tuyến nó.

Nguồn: Tránh Enums nơi bạn chỉ cần Ints


64
2018-01-27 22:53



Vì vậy, trong khi C # enums làm thực hiện rất tốt, Java enums không vì chúng phức tạp hơn. Do đó điểm đạn cuối cùng của tôi không thực sự đúng. Chính xác? - jnylen
Nó sẽ xuất hiện như vậy, vâng. - Sebastian Paaske Tørholm
Điều này có thể không hợp lệ nữa, hãy xem stackoverflow.com/questions/5143256/… - Viktor Dahl
Tài liệu Android vẫn khuyên không sử dụng enum: "Enums thường đòi hỏi nhiều gấp đôi bộ nhớ như hằng số tĩnh. Bạn nên tránh sử dụng enums trên Android."  developer.android.com/training/articles/memory.html#Overhead - ThomasW
Video này giải thích: youtube.com/watch?v=Hzs6OBcvNQE - Ultimo_m


Số nguyên nhỏ hơn và yêu cầu ít chi phí hơn, điều gì đó vẫn còn quan trọng trên thiết bị di động.


13
2018-01-27 22:52



Ngoài ra, bây giờ chúng tôi có công cụ tốt cho Android Studio và Lint. Ý tôi là chú thích IntDef và StringDef, cho phép khai báo một số loại typedef, vì vậy việc sử dụng hằng số int rất thuận tiện. blog.shamanland.com/2016/02/int-string-enum.html - Oleksii K.
vâng, nhưng về mô hình Retrofit thì sao? (và đối với các thư viện mạng khác mà tôi đoán) Bạn sẽ xác định phản hồi trạng thái như thế nào (ví dụ: thành công, thất bại, token_expired) để ánh xạ trực tiếp tới POJO? - mitsest


Một đồng nghiệp của tôi đã thực hiện một thử nghiệm nhỏ liên quan đến tình huống này. Anh ta tự động tạo class và một enum với cùng một lượng "enums". Tôi tin rằng ông đã tạo ra 30000 mục.

Kết quả là:

  • .class cho class khoảng 1200KB
  • .class cho enum khoảng 800KB

Hy vọng điều này sẽ giúp một ai đó.


5
2018-05-09 19:37



Tôi không nghĩ đó là thử nghiệm hợp lệ. Có 30000 enums / lĩnh vực tĩnh ở một nơi duy nhất không phải là một kịch bản thực tế. Bạn cần phải so sánh kích thước của một số lượng lớn các lớp nhỏ / enums ví dụ: 1000 lớp / enums 30 thuộc tính mỗi. Tôi đặt cược rằng tổng kích thước sẽ khá khác nhau. - Iwo Banas
@Iwo Banas Bất kỳ thử nghiệm nào cũng là một thử nghiệm hợp lệ. Không nói nó sẽ trả lời câu hỏi. Chỉ cần cung cấp nó như là thông tin bổ sung cho bất cứ ai có thể quan tâm. Và bỏ phiếu xuống dường như rất xứng đáng, vì vậy cảm ơn bạn. -_- - prolink007
Nó không cho thấy điều ngược lại? Enum đó sử dụng ít hơn? Và nó là bộ nhớ hoặc lưu trữ đó là 1200KB hoặc 800KB? - android developer