2011-10-09 42 views
9

tôi vẫn còn khá mới để lập trình Java và tôi đã nhìn qua một dự án mã nguồn mở và đã xem qua nàyChú thích của người dùng hoạt động như thế nào?

public @TileNetworkData int progressPart = 0; 

Tôi đã thấy việc sử dụng các @ trước nhưng chỉ để làm những việc như @override trước khi một thành viên. Trước sự ngạc nhiên của tôi nhìn lên định nghĩa nó mang lại cho tôi để mã người dùng

import java.lang.annotation.Inherited; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
public @interface TileNetworkData { 

    int staticSize() default -1; 

} 

được mã này đang làm gì, và nó là những gì hữu ích cho? Dường như nó đang thêm một số dạng siêu dữ liệu vào trường. Làm thế nào là một cái gì đó như thế này được sử dụng?

Làm một số Googleing Tôi thấy điều này được gọi là "Chú thích" nhưng mọi thứ gắn liền với nó đều đi qua đầu tôi. Bất kỳ loại ví dụ nào giống như thế này sẽ được sử dụng sẽ được đánh giá cao.

Trả lời

5

Annotations được sử dụng làm "siêu dữ liệu có thể đọc được" - chúng mô tả các trường, phương thức và lớp mà chúng gắn nhãn theo cách mà trình biên dịch và thời gian chạy có thể phân tích và thậm chí có thể hiểu được. Nếu bạn đã quen thuộc với .NET's attributes, bạn sẽ thấy rằng chú thích Java được sử dụng tương tự.

Ví dụ: chú thích TileNetworkData được xác định trong ví dụ của bạn được tự trang trí bằng chú thích Retention(RetentionPolicy.RUNTIME). Điều này cho trình biên dịch nhúng chú thích TileNetworkData vào bytecode cho các trường mà nó chú thích. Chú thích tương tự cũng cho biết thời gian chạy Java, khi nó tải các lớp với các trường có chú thích TileNetworkData, nó sẽ giữ lại chú thích TileNetworkData để phản ánh thời gian chạy.

Bây giờ, mã của bạn có thể phản ánh trên các lĩnh vực của một đối tượng để tìm các chú thích TileNetworkData và làm điều gì đó với các lĩnh vực nên chú thích:

// I haven't even compiled this code, and even if it works, it's still insane. 
// (others who know annotations better should feel free to edit or replace) 
public void copyTileNetworkDataToCache (Object data, Cache<?> cache) { 
    for (Field f : data.getClass().getFields()) { 
    if (f.isAnnotationPresent(TileNetworkData.class)) { 
     cache.save(f.get(data)); 
    } 
    } 
} 

Bạn thậm chí có thể viết mã mà dạy trình biên dịch Java how to interpret your annotations at compile time, sử dụng apt giao diện người dùng trong các thiết bị chuyển mạch JDK 5 và javac trong JDK 6 trở lên. Để tạo một ví dụ khác, việc truy cập mạng lưới có thể mất nhiều thời gian đến mức bạn muốn tránh sử dụng dữ liệu từ nó bất cứ khi nào có thể. Do đó, bạn có thể muốn tạo danh sách tất cả các lớp bao gồm các trường có chú thích TileNetworkData, vì vậy bạn có thể xem lại tất cả và có thể viết lại những trường không hoàn toàn cần truy cập vào mạng lưới xếp kề. Để làm điều này, bạn có thể viết một bộ xử lý chú thích in ra tất cả các lớp phù hợp, sau đó trỏ apt tại bộ xử lý khi bạn biên dịch.

2

Chú thích được sử dụng cho siêu dữ liệu, để mô tả các phương pháp, lớp học và các loại đối tượng khác.

Bạn có thể sử dụng để chỉ định siêu dữ liệu (mô tả dữ liệu) cho các lớp java của bạn. Ví dụ cổ điển là @Deprecated, đánh dấu phương thức là 'không được sử dụng trong tương lai'.

Ví dụ: bạn có thể sử dụng chúng để thêm thông tin cấu hình vào lớp java. Nếu bạn đang sử dụng Hibernate (một ORM), bạn thêm Chú thích vào lớp cho biết lớp này nên được điền từ thông tin có trong bảng cơ sở dữ liệu table_xxx và thông tin cột column_xxx phải được lưu trữ trong trường như vậy và trong trường đó.

Mã bạn đã đăng đang xác định Chú thích. Điều này sẽ cho phép chú thích này được sử dụng ở nơi khác trong mã của bạn. Nó nói rằng chú thích sẽ có sẵn khi chạy, @Retention(RetentionPolicy.RUNTIME) và chú thích đó sẽ có sẵn cho cả lớp sử dụng nó và bất kỳ lớp con nào của lớp đó.

Để biết thêm thông tin, xem câu trả lời cho How and where are Annotations used in Java?

+0

Điều này không hoàn toàn trả lời những gì OP yêu cầu cụ thể. – BoltClock

1

Các dữ liệu meta có thể được truy vấn thông qua phản ánh. Do đó, nếu có một mã chung chung void submitTileNetworkData(Object model) ở đâu đó trong mã, nó có thể lặp qua các trường model và tạo một kết xuất nhị phân dựa trên các chú thích TileNetworkData.

4

Ví dụ: Giao dịch ranh giới:

public class TransactionalThing { 
    @Transactional 
    public void doSomePersistenceStuff() { 
     Foo foo = loadAFoo(); 
     doSomeStuffWith(foo); 
     foo.setProcessed(true); 
    } 
} 

Sẽ có mã khác trông cho các phương pháp chú thích bởi @Transactional, bắt đầu một giao dịch trước khi phương pháp này được gọi, và cam kết (hoặc cuộn lại) giao dịch khi nó kết thúc . Bạn cũng có thể đưa thông tin trong chú thích về những thứ như, ví dụ, các quy tắc rollback:

@Transactional(rollbackFor = SomeException.class, 
       noRollbackFor = SomeOtherException.class) 

Và một lần nữa, nó chỉ lên đến mã quét các giao dịch này để đọc trong những thuộc tính và xử lý mọi thứ một cách thích hợp.

Các vấn đề liên quan