2010-09-29 9 views
10

Trong khi làm việc với các chú thích tôi vấp accross các đoạn mã sau (đó là chú thích Hibernate @NotNull):Mặc định phương thức hoàn trả giá trị trong Java giao diện

@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) 
@Retention(value = RetentionPolicy.RUNTIME) 
@Documented 
@Constraint(validatedBy = {}) 
public @interface NotNull { 

    @Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) 
    @Retention(value = RetentionPolicy.RUNTIME) 
    @Documented 
    public @interface List { 

     public NotNull[] value(); 
    } 

    public String message() default "{javax.validation.constraints.NotNull.message}"; 

    public Class<?>[] groups() default {}; 

    public Class<? extends Payload>[] payload() default {}; 
} 

tôi đã tự hỏi về những từ khóa default/xây dựng trong phương pháp định nghĩa mà tôi chưa bao giờ thấy trước đây. Như tôi đã hiểu, nó cho phép bạn xác định một giá trị mặc định cho phương thức này (hoặc thuộc tính chú thích).

Bây giờ tôi đã cố gắng áp dụng cấu trúc này cho một giao diện bình thường, nhưng nó không thành công. Điều này sẽ không biên dịch:

public interface DefaultTest { 
    public String test() default "value"; 
} 

Nhưng điều này sẽ làm việc:

public @interface DefaultTest { 
    public String test() default "value"; 
} 

Vì vậy, câu hỏi của tôi là: default từ khóa chú thích cụ thể? Và nếu có, những gì nói chống lại bằng cách sử dụng cấu trúc này trong định nghĩa giao diện bình thường?

Trả lời

16

Java 8 trở đi

Vâng, từ khóa mặc định bây giờ có thể được sử dụng trên giao diện. Để biết thêm chi tiết, xem Oracle's docs.

Việc triển khai hơi khác so với suy nghĩ của bạn. Nó sẽ là:

public interface DefaultTest { 
    default public String test() { 
     return "value"; 
    } 
} 

Java 7 và trước

Từ khóa mặc định chỉ có thể được sử dụng cho các chú thích.

Nếu bạn muốn có giá trị trả về mặc định cho giao diện, bạn cần phải sử dụng lớp trừu tượng thay thế.

public abstract class DefaultTest { 

    public String test() { 
    return "value"; 
    } 

} 
+1

Thừa kế nhiều giao diện mang lại cảm giác hoàn hảo. Cảm ơn bạn đã chỉ ra điều này. – MicSim

+0

Hóa ra bạn thực sự là nguyên nhân. Java 8 bây giờ cho phép bạn làm những gì bạn muốn! Tôi đã cập nhật câu trả lời của mình. – Pace

3

Từ khóa 'mặc định' ở đây không phải là chú thích cụ thể. Tính năng của java để cung cấp việc triển khai mặc định cho các phương thức giao diện.

Cần hành vi này: Giả sử ban đầu một xe giao diện được định nghĩa để hỗ trợ tất cả các phương pháp chức năng xe -

interface Vehicle { 
    void speed(); 

    ... 
    //other interface methods 
} 

Bây giờ các lớp học thực hiện giao diện xe này đã thực hiện những phương pháp trừu tượng.

Hiện tại trong tương lai Xe có khả năng bay. Vì vậy, bạn cần phải thêm tính năng bay là tốt. Bây giờ nếu bạn thêm phương thức flyingSpeed ​​() vào giao diện Xe, bạn cần phải sửa đổi tất cả các lớp hiện có để tránh phá vỡ mã. Giải pháp không khả thi.

Đối với tính tương thích ngược java đã cung cấp tính năng của Phương pháp mặc định. Vì vậy, bạn có thể thêm các phương thức mới để giao tiếp với việc thực hiện mặc định, do đó các lớp hiện tại sẽ không cần phải thực hiện phương thức đó. Và các lớp Xe mới có thể ghi đè lên các phương pháp đó theo nhu cầu của chúng.

interface Vehicle { 
    void speed(); 

    ... 
    //other interface methods 

    //default method 
    default void flyingSpeed() { 
    System.out.println("Default flying speed"); 
    } 
} 

Sử dụng cách này các lớp xe hiện có trước đây sẽ không cần triển khai phương pháp này.

Để biết thêm thông tin see tại đây.