A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© yuehaotian 中级黑马   /  2013-12-22 15:42  /  1102 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

注解是JDK1.5新功能,相当于一个标记,哪里加注解哪里就相当于有了一个标记,这些标记会分别由,源文件,class,和字节码识别

我想知道的是,都有哪些地方可以加注解,在不同的地方所加的注解,是否有特殊含义(还是视频中说的3类常用含义,过时--覆盖--压缩)

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

2 个回复

倒序浏览
视频中的那3个是属于jvm内建的注解,至于那些地方可以加注解,基本上你在一个程序中你认为能加注解的地方都可以加,只是大多数注解都有限制加注解的位置
构造方法,变量,方法,局部变量,类,接口。。。还有别的,
就比如ovveride 就只能加载方法上面,别的地方不能加,他在被定义的时候有声明
@Target(value=METHOD)              value值便代表他所能使用的地方
@Retention(value=SOURCE)
public @interface Override

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
详细的解答下你的疑问:还有不明白的话个别再问啊。

JDK5新特性-Annotation注解


1.Annotation:新版的ejb,Spring,hibernate,struts2有一部分也是基于注解的
2.3个JDK自带的注解:
(1)@SuppressWarnings注解:
public class AnnotationTest {
    public static void main(String[] args) {
        System.runFinalizersOnExit(true);
    }
}
用eclipse会发现中间加了一道线,意思是过时了,
用javac发现:使用或覆盖了已过时的 API这个警告
但是,当我们在main方法前边加上@SuppressWarnings("deprecation")的时候,再编译,就不再输出警告信息了。@SuppressWarnings("deprecation")这就是一个注解,用于告诉javac编译器该怎样。

一个注解就是一个类。

(2)@Deprecated注解:
假设我们的类中有一个类的一个方法:
public static void sayHello(){
  System.out.println("itcast");
}
我们现在想让这个类作废,该怎么做呢?
可以加上一个注解:@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。

(3)@Override:覆盖父类的方法
假如我们想覆盖类的equals方法:
public boolean equals(Point pt){
}
但是实际上这个方法并不是重写的Object的equals,如何限定我们就是覆盖的Object的equals而不会出错呢?当我们在方法前面加上@Override注解的时候,编译时就会提示我们其实并没有覆盖!
总结一下:注解就是一个标记,加了注解就相当于给程序打了一种标记。
标记可以加载包上,类上,方法上,成员变量,方法的参数,方法的局部变量上面。

3.如何应用注解?
应用注解就相当于调用一个特殊的类,首先得有这么一个注解类。

注解类:
@interface A{
}

应用了“注解类”的类
@A
Class B{
}

对应用了注解类的类进行反射操作的类。
Class C{
   B.class.isAnnotationPresent(A.class);
   A a=B.class.getAnnotion(A.class);
}

下面我们做一个例子:
public @interface ItCastAnnotation{}

@ItCastAnnotation
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
     if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
         ItCastAnnotation annotation=(ItCastAnnotation)                           

                AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
         System.out.println(annotation);
     }else System.out.println(false);
}
}
竟然输出是false,为什么呢?
原来需要这样修改注解类:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface ItCastAnnotation{
}

为我们的注解类添加注解,这叫注解的注解,就是元注解。
然后再来运行,输出结果:@edu.sdkd.ItCastAnnotation()

@Retention(RetentionPolicy.RUNTIME)这个注解的意思就是:要让注解一直保留到运行时。
当javac把源文件编译成class的时候,需要做一些处理,而当jvm用类加载器把class里面的二进制数据加载进内存的时候,也要做一些处理,然后生成字节码Class。
因此,一个注解的生命周期有三个阶段:源文件->class文件->字节码。在设计注解的时候就需要指定

注解存在的生命周期,用@Retention来指定,默认是保留在class阶段。

Override的Retention是保留在source阶段,SuppressWarnings也是给编译器看的,保留在sourfce阶段,Deprecated是保留在运行时Runtime。

Retention的取值是一个enum,这个enum的名字叫做:RetentionPolicy,有三个常量和两个方法,CLASS,RUNTIME,SOURCE和static RetentionPolicy valueOf(String name)  ,static

RetentionPolicy[] values() 。

下面再加一个注解:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
}
@Target意思是说作用的对象,是类还是方法等等,target的取值也是一个枚举ElementType,它里面有很多字段:ANNOTATION_TYPE,CONSTRUCTOR ,FIELD ,LOCAL_VARIABLE ,METHOD,PACKAGE ,PARAMETER,TYPE(包括Class, interface (包括注解), or enum declaration)。


4.如何为注解增加属性?
<font color="red">color就是属性
public @interface ItCastAnnotation{
String color();
}
注解有一个方法,返回一个字符串,也就是说这个注解有一个属性,他的名字就叫方法的名字color。那么在创建这个注解的时候,就需要给这个属性进行赋值。
@ItCastAnnotation(color="red")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
    if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
        ItCastAnnotation annotation=(ItCastAnnotation)                             

AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
        System.out.println(annotation.color());//输出red
     }else System.out.println(false);
}
}
有一个特殊的属性:value
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color();
String value();
}

@ItCastAnnotation(color="red",value="abs")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
  if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
     ItCastAnnotation annotation=(ItCastAnnotation)                  

AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
     System.out.println(annotation.color()+","+annotation.value());
  }else System.out.println(false);
}
}
如果注解只有value属性,那么就可以不写value。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color() default "red";//给属性提供一个默认值
String value();
}

@ItCastAnnotation("abs")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
  if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
     ItCastAnnotation annotation=(ItCastAnnotation)                  

AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
     System.out.println(annotation.color()+","+annotation.value());
  }else System.out.println(false);
}
}

从@Retention(RetentionPolicy.RUNTIME)我们可以知道:有一个属性是value,它的返回值类型是一个枚举RetentionPolicy。

5.为注解增加更复杂的类型
(1)增加数组属性:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr();
}
@ItCastAnnotation(value="abs",intArr={1,2,3})
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
  if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
     ItCastAnnotation annotation=(ItCastAnnotation)

AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
     System.out.println(java.util.Arrays.toString(annotation.intArr()));
  }else System.out.println(false);
}
}
输出1,2,3

如果数组里面只有一个元素,就可以不用{}也可以。

(2)假如属性是枚举类型:
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr() default {3,4,5};
Lamp lamp() default Lamp.RED;
}
public enum Lamp {
    RED,GREEn,YELLOW;
}
System.out.println(annotation.lamp());

(3)假如属性是注解类型:
新建一个注解:
public @interface MetaAnnotation {
     String value();
}
增加一个注解属性:
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr() default {3,4,5};
Lamp lamp() default Lamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("hello");
}
主调函数:
@ItCastAnnotation(value="abc",color="red",annotationAttr=@MetaAnnotation("world"))
System.out.println(annotation.annotationAttr());

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马