2017-02-06 38 views
1

我使用下面的代碼,在JDK8環境中使用了一個新註解屬性:在預先存在的編譯方面

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Client", namespace = "http://schemas.datacontract.org/2004/07/BLA.BLA.Model.Client", propOrder = { 
"birthDate", 
"email", 
"ip", 
"name", 
"phone" 
}) 
@Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2016-12-07T07:34:51+04:00", comments = "JAXB RI v2.2.4-2") 
public class Client { 

@XmlElementRef(name = "BirthDate", namespace = "http://schemas.datacontract.org/2004/07/BLA.BLA.Model.Client", type = JAXBElement.class, required = false) 
@Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2016-12-07T07:34:51+04:00", comments = "JAXB RI v2.2.4-2") 

該代碼在與maven`s建設者JDK8下編譯的應用程序使用目標設置爲1.6並在JDK6下運行。 (不要問我爲什麼:()

我想知道它是如何工作的呢?物業@XmlElementRef沒有屬性required在JDK6的版本,它不能用它來構建。

PS。我不問,爲什麼我可以編譯代碼,我感興趣的是爲什麼我可以運行它,是否因爲一些註解特定的語義,因爲我的代碼不知道這個屬性required,從來沒有使用它,或者因爲別的什麼?

+0

@ Sotirios-delimanolis我不認爲,我的問題是重複的。我編輯它,更清楚。 – glebiuskv

+0

你是什麼意思_不知道property_? –

+0

我的意思是,它是從1.6開始的'@ XmlElementRef',我不手動調用這個屬性,所以沒有地方,這個代碼被調用。 – glebiuskv

回答

2

這是一個試探性的答案,我並沒有聲稱是完全準確的,但在這個問題上似乎是合理的。

它在JLS所述,在二進制兼容性(重點煤礦):

13.5.7。註釋類型的演變

註釋類型的行爲與任何其他接口完全相同。 從註釋類型中添加或刪除元素與添加或刪除方法類似。控制註釋類型的其他更改需要考慮重要因素,但這些對Java虛擬機的二進制文件鏈接沒有影響。相反,這些更改會影響操縱註釋的反射API的行爲。這些API的文檔在對基礎註釋類型進行各種更改時指定了它們的行爲。

添加或刪除註釋對Java編程語言中程序的二進制表示的正確鏈接沒有影響。

如果我們指的是什麼說的接口:

13.5.3。接口成員

將方法添加到接口不會破壞與預先存在的二進制文件的兼容性。

我的理解是,@XmlElementRefrequiered「元素」在內部表示爲接口的方法。

因此,您可以像以前的任何其他界面一樣,推斷其與以前的JDK的兼容性。如果您使用給定接口的給定方法,則需要在代碼的接口聲明中進行編譯。這就是爲什麼您的代碼不能在2.2以前的JAXB版本上編譯(請參閱this:JDK6隨JAXB 2.1.10一起提供)。但是,如果你有已經編譯好的代碼(一個「預先構建的二進制文件」),只要沒有任何東西需要訪問上述方法(直接通過反射),那麼對於這個運行時就沒問題了方法不存在。

2

想想這樣:如果你有一個類實現一個接口,它不會傷害,如果它有更多的方法比接口指定。如果您將該類與具有更少方法的較早版本的界面一起使用,則它也不會造成任何損害。

在註釋的情況下,它通常更簡單,因爲典型的Reflection實現不會生成具有所有這些方法的類,但會生成一個proxy,其調用處理程序將通過查找方法的名稱來查找請求的值一個Map包含在類文件中發現的值。因此,通過接口方法調用比以往任何時候在該映射中具有更多的鍵都不會造成損害。

相關問題