若是一個父類添加了一個註解,子類是否能取到這個註解呢?以下java
package inheritance; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Main { public static void main(String[] args) { Type t = Son.class.getAnnotation(Type.class); if (t != null) { System.out.println(t.name()); } } } @Type(name = "Father") class Father { } class Son extends Father { } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Type { String name(); }
如上代碼,註解不會被子類繼承。若是想註解也被子類繼承,該怎麼辦呢?apache
只須要在註解定義裏修改一下,添加@Inheritedspa
@Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Type { String name(); }
關於@Inherited須要注意的:code
@XmlAccessorType用於標註該類的成員是否用於綁定到XML,例如XmlAccessType.PUBLIC_MEMBER表示,全部public字段都會被綁定(除去@XmlElement和@XmlTransient的標記,他們優先級更高)。
這個註解就是標記了@Inherited。orm
咱們知道序列化順序能夠由@XmlType(propOrder)去設置,那麼繼承後是什麼樣子呢?xml
package inheritance; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; public class Main { public static void main(String[] args) throws Exception { JAXBContext ctx = JAXBContext.newInstance(Son.class); Marshaller ms = ctx.createMarshaller(); ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); ms.marshal(new Son(), System.out); } } @XmlRootElement(name = "Father") @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) @XmlType(propOrder = { "two", "one" }) class Father { @XmlElement private String one = "one"; @XmlElement public String two = "two"; } @XmlRootElement(name = "Son") @XmlAccessorType(XmlAccessType.NONE) @XmlType(propOrder = { "four", "three" }) class Son extends Father { @XmlElement public String three = "three"; @XmlElement public String four = "four"; }
上述代碼會輸出繼承
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Son> <two>two</two> <one>one</one> <four>four</four> <three>three</three> </Son>
即父類成員先序列化,再子類成員,順序由各自類的@XmlType設置的順序決定。接口
那麼若是子類必定想控制父類成員的序列化順序,並且不一樣的子類還想各自定義父類成員的序列化順序怎麼辦?(CNM, 屁事真多)three
好吧,JAXB仍是能夠知足這種屁事兒的。get
package inheritance; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; public class Main { public static void main(String[] args) throws Exception { go(Son.class); go(Daughter.class); } private static void go(Class<?> clz) throws Exception { JAXBContext ctx = JAXBContext.newInstance(clz); Marshaller ms = ctx.createMarshaller(); ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); ms.marshal(clz.newInstance(), System.out); } } @XmlTransient class Father { @SuppressWarnings("unused") private String one = "one"; public String two = "two"; } @XmlRootElement(name = "Son") @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) @XmlType(propOrder = { "four", "three", "two" }) class Son extends Father { @XmlElement public String three = "three"; @XmlElement public String four = "four"; } @XmlRootElement(name = "Daughter") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(propOrder = { "one", "two", "three", "four" }) class Daughter extends Father { @XmlElement public String three = "three"; @XmlElement public String four = "four"; }
上述代碼將輸出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Son> <four>four</four> <three>three</three> <two>two</two> </Son> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Daughter> <one>one</one> <two>two</two> <three>three</three> <four>four</four> </Daughter>
解釋以下:
import java.io.FileReader; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.sax.SAXSource; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; public class Demo2 { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(MyBean.class); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); spf.setFeature("http://xml.org/sax/features/validation", false); spf.setNamespaceAware(true); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); InputSource inputSource = new InputSource( new FileReader("myfile.xml")); SAXSource source = new SAXSource(xmlReader, inputSource); Unmarshaller unmarshaller = jc.createUnmarshaller(); MyBean foo = (MyBean) unmarshaller.unmarshal(source); } }