您的位置:首页 > 职场人生

16--黑马程序员--基础加强之注解

2015-05-13 09:21 381 查看
----------------------ASP.Net+Unity开发.Net培训、期待与您交流!
----------------------

一.注解基础知识点
1.概念

注解:也叫注释,也叫元数据。一种代码级别的说明。它是是JDK5.0及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)。

2.作用

注解有三个作用:

1)编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】

2)代码分析:通过代码里标识的元数据对代码进行分析【使用反射】

3)编译检查:通过代码里标识的元数据让编译器能过实现基本的编译检查【Override】

3.注解所在包

包 java.lang 中包含所有定义自定义注解所需用到的原注解和接口。如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。

该包同时定义了三个元注SuppressWarnings,Deprecated,Override。下面将在实例中逐个讲解他们的作用,及使用方法。

二.元注解详解

1.SuppressWarnings

简介:java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一。可以标注在类、字段、方法、参数、构造方法,以及局部变量上。

作用:告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。

使用:

@SuppressWarnings("")

@SuppressWarnings({})

@SuppressWarnings(value={})

根据sun的官方文档描述:

将由编译器在注释的元素中取消显示的警告集。允许使用重复的名称。忽略第二个和后面出现的名称。出现未被识别的警告名不是 错误:编译器必须忽略无法识别的所有警告名。但如果某个注释包含未被识别的警告名,那么编译器可以随意发出一个警告。

各编译器供应商应该将它们所支持的警告名连同注释类型一起记录。鼓励各供应商之间相互合作,确保在多个编译器中使用相同的名称。

我们可以看到,当用Myeclipse调用一个过时的方法时,它会自动在那个方法名上划一道横线,提示编程人员这是一个过时的方法,建议不要再调用它。而在cmd调试此程序也会有响应的提示:

这个时候我们要是在在main方法上添加一个注解:@SuppressWarnings("deprecation"),此注解的作用就是告诉编译器,虽然我用的方法过时了,但是我还是坚持要用,你就不要再提示了。

虽然Myeclipse编译器依然有横线,但在cmd调试时,就不会有相关的过时提示了。
2.Deprecated

作用:用 @Deprecated注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。

其次,请注意标题,这两个标记有大小写之分,一个是D,一个是d。

源代码标记@Deprecated是在JDK1.5中作为内置的annotation引入的,用于表明类(class)、方法(method)、字段(field)已经不再推荐使用,并且在以后的JDK版本中可能将其删除,编译器在默认情况下检测到有此标记的时候会提示警告信息。

Java注释中的@deprecated用于在用Javadoc工具生成文档的时候,标注此类/接口、方法、字段已经被废止。不过后者还有一个功能就是和源代码标记@Deprecated同样的功能,在JDK1.4版本之后,该功能被@Deprecated所取代。

代码示例:

3.Override

简介:@Override是伪代码,表示重写。有时我们需要覆盖父类的方法,但是可能方法名或者参数会出现不小心写错的情况。这时候就可以为这个方法打上@Override注解,如果有任何差错,eclipse就会报错。

作用:

1)可以当注释用,方便阅读;

2)编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。比如你如果没写@Override而你下面的方法名又写错了,这时你的编译器是可以通过的(它以为这个方法是你的子类中自己增加的方法)。

sun公司的官方解释:表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。

代码示例:

[html] view
plaincopy





public class OverrideDemo {

/**Override注解的应用

* @黑马ZWF

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Checket c = new Checket();

c.foo();

}

}

class Base { //父类

public Base(){

System.out.println("Base");

}

public void foo(){ //父类定义方法

System.out.println("foo in father");

}

}

class Checket extends Base {

public Checket(){

super();

System.out.println("Checket");

}

@Override

public void foo(){ //子类复写父类方法

System.out.println("foo in son");

}

}

这个例子中,子类Checketfoo函数覆写了父类Base中的foo方法,而@Override 关键字(我就把它理解成了关键字)的作用在于,告诉编译器,如果foo这个方法存在于父类中,那么编译通过,如果在父类中不存在,那么就会报错:

三.注解的反射调用

注解是一个特殊的类,关键字不是class。而是@interface。它相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好了这个注解类。就像你要调用某个类,得先有开发好这个类。

[html] view
plaincopy





@WfAnnotation

class AnnotationDemo3 {

/**

* 注解的反射调用

* @黑马ZWF

*/

public static void main(String[] args) {

if(AnnotationDemo3.class.isAnnotationPresent(WfAnnotation.class)){

WfAnnotation annotation = (WfAnnotation)AnnotationDemo3.class.getAnnotation(WfAnnotation.class);

System.out.println(annotation ); //输出结果@注解.WfAnnotation()

}

}

}

@Retention(RetentionPolicy.RUNTIME)

@interface WfAnnotation {

}

这里注意,注解的三个生命周期:source,class,内存里的二进制码

编译器在进行将source转换为class和将class转换为内存里的二进制编码的时候都有可能将注解去掉。

因此要在上面的注解上头上再加注解:RententionPolicy.RUNTIME表示注解生命周期一直到运行期。也就是内存里的二进制码

四.为注解增加各种属性

1.什么是注解的属性

一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是黑马的学生,否则,就不是。如果还想区分出是黑马哪个班的学生,这时候可以为胸牌再增加一个属性来进行区分。

加了属性的标记效果为:@MyAnnotation(color="red")。

2.定义基本类型的属性和应用属性:

在注解类中增加String color(); 被添加的注解设置属性值:@MyAnnotation(color="red")。

用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法

MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);

System.out.println(a.color());

可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象。

3.为属性指定缺省值:

String color() default "yellow";

value属性:String value() default "zxx";

如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@MyAnnotation("lhm")。

4.数组类型的属性

int [] arrayAttr() default {1,2,3};

被添加的注解设置属性值:@MyAnnotation(arrayAttr={2,3,4})。

如果数组属性中只有一个元素,这时候属性值部分可以省略大括号。

5.枚举类型的属性

EnumTest.TrafficLamp lamp() ;

被添加的注解设置属性值:@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)。

6.注解类型的属性:

MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx"); 被添加的注解设置属性值: @MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )

可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是 MetaAnnotation类的一个实例对象,调用代码如下:

MetaAnnotation ma = myAnnotation.annotationAttr();

System.out.println(ma.value());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: