2011-10-09 83 views
9

我仍然相當新的Java編程,我一直在尋找在一個開源項目,連同這個用戶註釋如何工作?

public @TileNetworkData int progressPart = 0; 

來到我已經看到了使用@之前,但只有一個成員之前做的事情一樣@override。令我吃驚的看着了定義,它給我帶來了用戶代碼

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; 

} 

這是什麼代碼做的,什麼是它有用嗎?它看起來正在向該領域添加某種形式的元數據。這是怎麼用的?

做一些Googleing我發現這叫做「Annotations」,但是附加到它的所有東西都在我頭上。任何類似這樣的例子將被使用的例子將不勝感激。

回答

5

Annotations被用作「機器可讀的元數據」 - 它們以編譯器和運行時可以解析並可能理解的方式描述它們標記的字段,方法和類。如果您熟悉.NET's attributes,則會發現Java註釋的使用方式與此類似。

例如,示例中定義的TileNetworkData註釋本身用註釋Retention(RetentionPolicy.RUNTIME)進行了修飾。這告訴編譯器將TileNetworkData註釋嵌入到它註釋的字段的字節碼中。相同的註釋也告訴Java運行時,當它加載帶有TileNetworkData註釋的字段的類時,它應該保留用於運行時反射的TileNetworkData註釋。

現在,你的代碼可以體現在對象的領域找到TileNetworkData批註,做一些有這麼註釋字段:

// 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)); 
    } 
    } 
} 

你甚至可以寫,教Java編譯器how to interpret your annotations at compile time,使用apt代碼JDK 5中的前端和JDK 6及更高版本中的javac開關。爲了彌補另一個蹩腳的例子,訪問瓷磚網絡可能會花費很長時間,以至於您希望儘可能避免使用數據。因此,您可能希望列出包含TileNetworkData註釋字段的所有類的列表,以便您可以查看所有類,並可能重寫那些並非絕對需要訪問切片網絡的類。要做到這一點,你可以編寫一個註釋處理器,打印出所有匹配的類,然後在編譯時在處理器處指向apt

2

註解用於元數據,用於描述方法,類和其他類型的對象。

您可以使用將元數據(數據的描述)分配給您的java類。典型的例子是@Deprecated,這標誌着一種方法'不會在未來使用'。

例如,您可以使用它們將配置信息添加到java類。如果您使用的是Hibernate(一個ORM),您可以向該類添加註釋,說明應該使用數據庫表table_xxx中包含的信息來填充此類,並且信息應該存儲在類的此類字段中。

您發佈的代碼定義了註釋。這將允許此註釋在代碼中的其他地方使用。這是說註釋將在運行時可用,@Retention(RetentionPolicy.RUNTIME),並且Annotation應該對使用它的類和該類的任何子類都可用。

有關詳細信息,請參閱答案How and where are Annotations used in Java?

+0

這並不完全回答OP特別要求的內容。 – BoltClock

1

的元數據可以通過反射進行查詢。因此,如果代碼中有一個通用的void submitTileNetworkData(Object model),它可以遍歷model的字段並基於TileNetworkData註釋構建二進制轉儲。

4

實施例:事務劃分:

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

會有其他代碼查找由@Transactional註解的方法,啓動一個被調用的方法之前的事務,並提交(或回退),當它結束該交易。你也可以把信息之類的東西的註解,例如,回滾規則:

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

再次,它只是到那個掃描這些交易中的屬性讀取,妥善處理事情的代碼。