2016-02-25 13 views
32

Tôi đang cố gắng triển khai chú thích @IntDef trong phát triển Android.Android - Có ok để đặt các giá trị @IntDef bên trong @interface không?

Đầu tiên Phương pháp: nó trông tuyệt vời với định nghĩa tách ra trong một lớp học Constant.java:

public class Constant { 
    @IntDef(value={SORT_PRICE, SORT_TIME, SORT_DURATION}) 
    @Retention(RetentionPolicy.SOURCE) 
    public @interface SortType{} 
    public static final int SORT_PRICE = 0; 
    public static final int SORT_TIME = 1; 
    public static final int SORT_DURATION = 2; 
} 

Cách sử dụng:

@Constant.SortType int sortType = Constant.SORT_PRICE; 

Nhưng mọi thứ trở nên một hỗn độn rất nhiều khi có nhiều định nghĩa (ví dụ như loại người dùng , StoreType, vv) trong một tệp.

Second Phương pháp: Vì vậy, tôi đã đưa ra một cái gì đó như thế này để các giá trị riêng biệt giữa định nghĩa:

public class Constant { 
    @IntDef(value={SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) 
    @Retention(RetentionPolicy.SOURCE) 
    public @interface SortTypeDef{} 

    public static class SortType{ 
     public static final int PRICE = 0; 
     public static final int TIME = 1; 
     public static final int DURATION = 2; 
    } 
} 

Cách sử dụng:

@Constant.SortTypeDef int sortType = Constant.SortType.PRICE; 

Nhưng như bạn thấy, tôi đã tạo ra hai tên khác nhau cho nó: SortTypeDefSortType

Thứ ba Hod: Tôi cố gắng để di chuyển danh sách các giá trị có thể bên trong @interface:

public class Constant { 
    @IntDef(value={SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) 
    @Retention(RetentionPolicy.SOURCE) 
    public @interface SortType{ 
     int PRICE = 0; 
     int TIME = 1; 
     int DURATION = 2; 
    } 
} 

Cách sử dụng

@Constant.SortType int sortType = Constant.SortType.PRICE; 

Trong khi nó không làm việc, tôi không biết nhược điểm là gì. Bạn có thể đặt các giá trị có thể có của @IntDef bên trong @interface không? Có bất kỳ khác biệt hiệu suất nào trong ba phương pháp trên không?

+0

Bạn đã tìm thấy một giải pháp cho câu hỏi này? Tôi đang tự hỏi bây giờ ... –

+2

@IgorGanapolsky chưa, nhưng tôi đang tiếp tục sử dụng phương pháp thứ ba trên mã sản xuất và cho đến nay không có vấn đề gì. Tôi nghĩ cách tốt nhất để kiểm tra là bằng cách lược tả (sử dụng, số lượng hằng số, v.v.). –

+0

Chú thích IntDef chỉ có RetentionPolicy.SOURCE và do đó chỉ được sử dụng bởi bộ xử lý chú thích trình biên dịch. Nó không thể cho nó có ảnh hưởng đến hiệu suất thời gian chạy trừ khi bộ xử lý chú thích đang làm điều gì đó rất bí truyền, chẳng hạn như sử dụng việc dệt bytecode hoặc tạo mã để chèn kiểm tra thời gian chạy vào mã của bạn. –

Trả lời

0

Có vẻ như một nơi tốt cho một emum ...

enum công SortEnum { THỜI GIAN, GIÁ , LÚC NÀO; }

+0

idk, tôi đã tránh enum kể từ khi tôi xem https://www.youtube.com/watch?v=Hzs6OBcvNQE. Cấp rằng video là 2 năm và nhiều thứ có thể đã thay đổi. –

+0

IntDefs được thiết kế đặc biệt để được thay thế Enum trong các hệ thống hạn chế tài nguyên. Đề xuất thay thế chúng bằng Enums không trả lời câu hỏi cũng như góp phần vào cuộc trò chuyện. – TBridges42

+1

Đã không nhận thức được vấn đề Enum trong Android cho đến khi Ahmad chỉ ra. Được sử dụng Java mãi mãi, nhưng không phải Android cho đến gần đây, và nó xuất hiện với tôi OP đã thực hiện một mô hình chống. Nhưng, kể từ khi nghiên cứu những gì dường như là một vấn đề với Enums trên Android, tôi sẽ tránh chúng và kiểm tra IntDefs. – NinePlanFailed

1

Tôi đến đây hy vọng tìm hiểu lý do tại sao tài liệu Android hiển thị phương pháp đầu tiên của bạn, nhưng phương pháp thứ ba đã hoạt động tốt cho tôi trong mã sản xuất trong nhiều tháng. Tôi chưa thấy lý do nào để không làm theo cách đó. Như bạn đã nói, nó dọn dẹp không gian tên khi bạn có thể có nhiều tập hợp các hằng số liên quan.

3

Để làm cho phương pháp thứ ba của bạn hoạt động, bạn nên đặt tên values như trong giao diện. tôi đã sử dụng mã của bạn và làm cho nó hoạt động:

public class Constant { 
    @IntDef(value = {SortType.PRICE, SortType.TIME, SortType.DURATION}) 
    @Retention(RetentionPolicy.SOURCE) 
    @interface SortType { 
     int PRICE = 0; 
     int TIME = 1; 
     int DURATION = 2; 
    } 
} 

Hoặc

public class Constant { 
    @IntDef(value = {SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) 
    @Retention(RetentionPolicy.SOURCE) 
    @interface SortType { 
     int SORT_PRICE = 0; 
     int SORT_TIME = 1; 
     int SORT_DURATION = 2; 
    } 
} 

Cách sử dụng cho thứ hai:

@Constant.SortType int sortType = Constant.SortType.SORT_DURATION; 

Chọn một, cả hai nên làm việc.

3

Câu trả lời ngắn: đối với các dự án đơn giản, không sao, nhưng đối với những dự án phức tạp thì phương pháp đầu tiên được ưu tiên hơn.

Long trả lời: Mặc dù bytecode cho sortType là giống hệt nhau trong cả ba trường hợp, có một sự khác biệt. Khóa nằm trong chú thích Retention, đặt chính sách lưu giữ thành SOURCE. Điều đó có nghĩa là chú thích SortType của bạn là "to be discarded by the compiler", do đó mã bytecode cho chú thích không được tạo.

Phương pháp đầu tiên xác định các trường tĩnh thông thường bên ngoài chú thích, với bytecode thông thường được tạo cho chúng. Trường hợp thứ hai và thứ ba xác định các hằng số trong các chú thích, và bytecode cho các hằng số không được tạo ra.

Nếu trình biên dịch có quyền truy cập vào tệp nguồn chứa khai báo SortType của bạn, một trong hai phương pháp là tốt và bytecode cho sortType giống hệt nhau. Nhưng nếu mã nguồn không thể truy cập được (ví dụ: bạn chỉ biên soạn thư viện), chú thích không thể truy cập được. Đối với phương pháp tiếp cận đầu tiên, chỉ chú thích chính nó là không thể truy cập, nhưng đối với những người sau này, hằng số giá trị không thể truy cập quá.

Tôi đã sử dụng phương pháp thứ ba là phương pháp sạch và có cấu trúc nhất. Tôi đã từng đến một ngày tôi gặp phải vấn đề: khi tôi bắt đầu viết các bài kiểm tra Espresso cho mã đó, trình biên dịch không có quyền truy cập vào mã nguồn xác định chú thích. Tôi phải chuyển sang khai báo chính thức IntDef hoặc sử dụng các giá trị số nguyên thay vì hằng số ký hiệu cho thử nghiệm.

Vì vậy, mấu chốt là:

  • dính vào con đường kinh điển trừ khi chú thích của mình là nội bộ để mã của bạn và bạn không đề cập đến nó từ bất cứ nơi nào khác, bao gồm kiểm tra
Các vấn đề liên quan