若是一个父类添加了一个注解,子类是否能取到这个注解呢?以下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); } }