|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
令人可喜的是java现在已经开源了,所以我想我上述的想法也许有一天会实现,因为java一直都是不断创新的语言,每次创新都会给我们惊喜,这也是我喜欢java的一个原因。j2se正文(annotation)
J2SE5.0经由过程引进正文(Annotation)的观点增加了对元数据的撑持。
一个@xxx情势的正文能够当做一个润色符来利用,它能够放在任何一个润色符能够呈现的中央。public,static,final都是java言语的润色符,正文能够写在它们能够呈现的任何中央。
举个例子,能够看上面一段代码:
publicclassAnnotationExample{
public@OverrideinthashCode(){
returnsuper.hashCode();
}
}
在这个例子中我们利用了一个java言语API中已有界说的正文@Override,经由过程在办法hashCode()中利用这个正文,申明了hashCode是一个掩盖了父类办法的办法。
至于正文的详细寄义我们在今后部分会申明。
假如你想利用一个类,你必需起首找到它的界说,大概你本人对它举行界说。正文也是必要界说的,任意在代码中拔出一个@XXX之类的正文是不克不及够经由过程编译的。
一个最复杂的Annotation界说相似于接口的界说,就象上面的代码:
public@interfaceInfo{
}
正如你所看到的,内里甚么都没有,可是即便是如许,我们也能够在程序里利用它:
public@InfoStringinformation;
如许的一种甚么都没有界说的空正文我们称为标志正文(markerannotations)。
我们能够在个中增加一个成员的界说:
public@interfaceInfo{
Stringauthor();
}
这里值得注重的一点是,正文类中办法的界说不克不及是公有的,假如你不在后面加public关头字,编译器会默许为它是私有的。
在增加上author的界说后,本来那种只写了一个@Info的正文就必需修正了,以后的正文必需如许写:
public@Info(author="myname")voidafunction(){
}
一个正文的成员能够有默许值:
public@interfaceInfo{
Stringauthor()default"myname";
}
利用默许值有甚么优点呢?我们能够从头如许写了:
public@Infovoidafunction(){
}
在做标志时,假如确认某个成员的值和它的默许值不异,我们就能够疏忽它,而不用显式地给每一个成员赋值,如许就加重了代码量。
假如我们增加的这个成员名字叫做value的话,也就是:
public@interfaceInfo{
Stringvalue();
}
就有了别的一种正文的用法:我们能够间接写出如许的正文@Info(“information”),而不用写@Info(value=”information”),括号里的值会主动传送给value。如许的一种正文称为单值正文(Single-valueannotations)
一个正文能够有良多范例分歧的成员,如许的一种正文称为完全正文(fullannotations)。
一个正文中的成员范例只可以是原生范例,字符串,Class范例,正文范例,列举范例,大概一维数组。
假定我们如今有一个正文界说:
public@interfaceCompany{
Stringvalue();
}
如今我们但愿界说别的一个正文,这个正文范例反应了一团体的信息:
public@interfacePerson{
publicenumGender{MALE,FEMALE};
Stringname();
intage();
Companycompany();
Gendergender()defaultGender.MALE;
Stringdescription()default"";
}
在程序代码中增加这类范例的正文时能够这么写:
@Person(age=23,name="MyName",gender=Person.Gender.FEMALE,company=@Company("FooCorporation"))
在java.lang包中界说了三种正文,分离是:
nDeprecated:和已往javadoc中@deprecated寄义不异
nOverride:暗示办法掩盖了父类中的办法
nSuppressWarnings:利用这个正文可使编译器疏忽特定范例的告诫信息
详细寄义能够参照api文档。
我们晓得,正文的引进,为java言语增加了元数据的表达体例,而元数据就是关于数据的数据。在java中,另有关于正文的正文,我们响应的称之为元正文(meta-annotations)
在java中,我们可使用4种事后界说的正文对正文界说举行正文,这4种正文是:
nTarget:指明正文能够在哪些代码段中利用,以免对正文的误用。
nRetention:申明编译器在编译和运转时是不是疏忽该种正文
nDocumented:申明正文是不是呈现在Javadoc中
nInherited:当我们在一个类中利用了某种正文,偶然候会但愿未来它的一切子类中都包括有该种正文信息,假如在正文界说中增加了@Inherited,那末这类正文就会被挪用者的子类承继
当我们在一个类中利用正文界说了一系列的元数据以后,我们应当怎样猎取这些元数据呢?我们经由过程上面的例子来讲明。
Annotation的界说仍旧利用列出来的两个,由于我们必要在取得类文件中的正文信息,以是必需在正文界说中增加Retention正文。
起首我们界说两个正文,正文Todo申明了另有甚么事变必要做:
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public@interfaceTodo{
Stringvalue();
}
正文Author申明了一个办法大概类的界说者:
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public@interfaceAuthor{
publicenumGender{MALE,FEMALE};
Stringname();
Stringemail();
Gendergender()defaultGender.MALE;
}
然后我们在一个复杂的类中增加这两品种型的正文:
public@Todo("deletethisclass")classFoo{
publicvoidmethodA(){}
public@Author(name="B",email="b@Foo.com")voidmethodB(){
}
public@Author(name="A",email="a@Foo.com")StringfieldA;
}
经由过程上面一段代码我们能够提取响应的元数据:
importjava.lang.reflect.Method;
publicclassGetAnnotations{
publicstaticvoidmain(String[]args){
try{
Class<?>klass=Class.forName(args[0]);
if(klass.isAnnotationPresent(Todo.class))
{
Todot=klass.getAnnotation(Todo.class);
System.out.println(t);
}
for(Methodm:klass.getMethods())
{
if(m.isAnnotationPresent(Author.class))
{
Authora=m.getAnnotation(Author.class);
System.out.printf("Method:%s,Author:%s%n",m.getName(),a);
}
}
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
利用上面的命令交运路程序:
javaGetAnnotationsFoo
运转了局以下:
@Todo(value=deletethisclass)
Method:methodB,Author:@Author(gender=MALE,name=B,email=b@Foo.com)
再举这样一个例子:如果你想对一个数字取绝对值,你会怎么做呢?java的做法是intc=Math.abs(-166);而ruby的做法是:c=-166.abs。呵呵,这就看出了java与ruby的区别。 |
|