java中的简单注解、集合的简单复习

注解

JDK5.0以上的版本引入了一项新特性:Annotation,中文翻译成注解,是用来为程序元素(类、方法、成员变量等)设置说明和解释的一种元数据,Java开发和部署工具可以读取这些注解,并以某种形式处理这些注解。

注解(annotation)是JDK 5.0以上版本新增加的功能。它可以添加到程序的任何元素(包声明、类型声明、构造方法、方法、成员变量等)上,用来设置一些说明和解释,Java开发和部署工具可以读取这些注释,并以某种形式处理这些注释。

注解是在代码里做的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。

通过使用注解,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的描述源代码的信息(这些信息被存储在注解的“name=value”键-值对中)。代码分析工具、开发和部署工具可以通过这些补充的、描述源代码的信息进行验证或者进行部署。

注解类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数、局部变量的声明。

需要注意的是,注解被用来为程序元素设置元数据,它不影响程序代码的执行,即无论增加、删除注解,程序的执行都不受任何影响。如果希望让程序中的注解起一定作用,只有通过配套的工具对注解中的元数据信息进行提取、访问,根据这些元数据增加额外功能和处理等。

JDK内置的基本注解类型:

Java的注解采用“@”标记形式,后面跟上注解类型名称,如果注解需要数据,通过“name=value”向注解提供数据。

注解类型和注解的区别:注解类型是某一类型注解的定义,类似于类。注解是某一注解类型的一个具体实例,类似于该类的实例。

预定义了三个注解:

重写Override :是一个限定重写方法的注解类型,用来指明被注解的方法必须是重写超类方法的方法,只能用于方法上。编译器在编译源代码时会检查用@Override标注的方法是否有重写父类的方法。

警告Deprecated :用来标记已过时成员的注解类型,用来指明被注解的方法是一个过时的方法,不建议使用了。当编译调用到被标注为Deprecated的方法的类时,编译器就会产生警告。

抑制警告SuppressWarnings :是抑制编译器警告的注解类型,用来指明被注解的方法、变量或类在编译时如果有警告信息,就阻止警告。
@SuppressWarnings(value={"unchecked", "deprecation"}),  

自定义注解类型 :

Java中允许程序员自定义注解类型。注解类型的定义和接口类型的定义差不多,只是在interface前面多了一个“@”。
/** 自定义注解类型 */
public @interface MyAnnotation {
}

或者
/**带属性的注解类型*/
public @interface MyAnnotation{
      String value();  //定义一个属性

使用注解
/** 使用自定义注解类型:MyAnnotation */
class UserMyAnnotation{
     @MyAnnotation("abc")//abc”传给了属性value
     public void myMethod(){
          System.out.println("使用自定义的注解");
      }
}

约定,如果使用注解时没有显式指定属性名,却指定了属性值,而这个注解类型又有名为value的属性,就将这个值赋给value属性。如果没有在注解类型中定义名为value的属性,就会出现编译错误。 

16.1 在定义注解类型时,还可以给它的属性指定默认值。

//定义自己的一个枚举类型

enum Status {ACTIVE, INACTIVE};

//定义注解类型

public @interface MyAnnotation{

    String value();

    Status status() default Status.ACTIVE;   

//status属性指定默认值

}

那么,在使用时,就可以不需要给status属性显式指定值了,它就会使用默认值。

/** 使用自定义注解类型:MyAnnotation */

class UserMyAnnotation{

//value属性的值为“abc”;status属性使用默认值Status.ACTIVE

@MyAnnotation(value="abc")  

public void myMethod(){

System.out.println("使用自定义的注解");

}

}

当然,你还是可以给有默认的属性显式指定值的。

class UserMyAnnotation{

     @MyAnnotation(value="xxx", status=Status.INACTIVE)

     public void myMethod2(){

    System.out.println("使用自定义的注解");

     }

}

这里使用这个自定义注解类型时,给它的多个属性赋了值,多个属性之间用逗号“,”分隔。

对注解进行注解 :

 JDK 5.0中提供了四种专门用在注解上的注解类型,分别是TargetRetentionDocumentedInherited。 

目标Target 

枚举ElementType:定义了注解类型可应用于Java程序的哪些元素。public enum ElementType{
            TYPE, //适用于类、接口、枚举
            FIELD,//适用于成员字段
            METHOD, //适用于方法
            PARAMETER, //适用于方法的参数
            CONSTRUCTOR, //适用于构造方法
            LOCAL_VARIABLE,//适用于局部变
            ANNOTATION_TYPE, //适用于注解类型
            PACKAGE//适用于包    }

16.3 目标Target注解类型的使用。

package com.qiujy.corejava16;

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) 

@interface MethodAnnotation{

}

@MethodAnnotation  //作用在类上----编译出错

public class TestTarget {

@MethodAnnotation  //作用在方法上----正确

public void myMethod(){

}

}

类型Retention 
既然可以自定义注解类型,当然也可以读取程序中的注解信息。但是注解只有被保存在class文件中才可以被读出来。Java编译器中处理类中出现的注解时,有以下3种方式。

编译器处理完后,不保留注解到编译后的类文件中。

将注解保留在编译后的类文件中,但是在运行时忽略它。

将注解保留在编译后的类文件中,并在第一次加载类时读取它。

3种方式对应于java.lang.annotation.RetentionPolicy枚举的3个值。该枚举的源代码如下所示:

package java.lang.annotation;

public enum RetentionPolicy {

   SOURCE, //编译器处理完后,并不将它保留到编译后的类文件中

    CLASS, //编译器将注解保留在编译后的类文件中,但是在运行时忽略它

    RUNTIME //编译器将注解保留在编译后的类文件中,并在第一次加载类时读取它

}

Retention就是用来设置注解是否保存在class文件中的。

3种方式对应于java.lang.annotation.RetentionPolicy枚举的3个值。该枚举的源代码如下所示:

package java.lang.annotation;

public enum RetentionPolicy {

   SOURCE, //编译器处理完后,并不将它保留到编译后的类文件中

    CLASS, //编译器将注解保留在编译后的类文件中,但是在运行时忽略它

    RUNTIME //编译器将注解保留在编译后的类文件中,并在第一次加载类时读取它

}

Retention就是用来设置注解是否保存在class文件中的。

16.4 注解Retention的使用。

@Retention(RetentionPolicy.SOURCE)

@interface MyAnnotation1 { }

@interface MyAnnotation2 { }

@Retention(RetentionPolicy.RUNTIME)

@interface MyAnnotation3 {}

文档Documented 
这个注解类型和文档有关。默认的情况下,在使用javadoc自动生成文档时,注解将被忽略掉。如果想在文档中也包含注解,必须使用Documented定义。另外需要注意的是:定义为Documented的注解必须设置Retention的值为RetentionPolicy.RUNTIME

16.5 文档Documented注解的使用。

@Documented

@Retention(RetentionPolicy.RUNTIME)

@interface DocAnnotation {

}

继承Inherited 
在默认的情况下,父类上的注解并不会被子类继承。如果要让这个注解可以被子类上继承,就必须给这个注解类型定义上添加Inherited注解。

利用反射获取注解信息:

JDK 5.0 API中的java.lang.reflect.AnnotatedElement接口中定义了四种反射性读取注解信息的方法。

public Annotation getAnnotation(Class annotationType):如果存在该元素的指定类型的注解,则返回这些注解,否则返回 null

public Annotation[] getAnnotations():返回此元素上存在的所有注解。

public Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注解。

public boolean isAnnotationPresent(Class  annotationType):如果指定类型的注解存在于此元素上,则返回true,否则返回false

java.lang.Class类和java.lang.reflect包中的ConstructorFieldMethodPackage类都实现了AnnotationElement接口,可以从这些类的实例上分别取得标注于其上的注解及相关信息。

package com.hbsi.annotation;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

/*定义一个功能,用于去除ArrayList中的重复元素。

 * 1.存入的是字符串

 * 2.存入一个自定义对象。

 * 

 * 思路:

 * 1.创建一个新集合,存放非重复元素

 * 2.对原来的集合进行遍历

 * 3.在遍历的过程中进行判断元素是否在新集合中存在

 * 4.如果不存在,添加。

 * 5.返回新集合。

 * 

 * */

public class Test1 {

/**

 * @param args

 */

public static void main(String[] args) {

/*List list=new ArrayList();

list.add("abc1");

list.add("abc2");

list.add("abc2");

list.add("abc3");

System.out.println(list);

list=getSingList(list);

System.out.println(list);*/

List list=new ArrayList();

list.add(new Student("aa",23));

list.add(new Student("bb",24));

list.add(new Student("cc",25));

list.add(new Student("bb",24));

System.out.println(list);

list=getSingList(list);

System.out.println(list);

}

public static List getSingList(List list){

//创建一个新集合

List newList=new ArrayList();

/*Iterator it=list.iterator();

while(it.hasNext()){

Object obj=it.next();

if(!(newList.contains(obj))){

newList.add(obj);

}*/

for(Iterator it=list.iterator();it.hasNext();){

Object obj=it.next();

if(!(newList.contains(obj))){

newList.add(obj);

}

}

return newList;

}

}

package com.hbsi.annotation;

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Map;

import java.util.Set;

/*每个学生有自己的姓名和年龄

  每个学生都有自己的籍贯,籍贯是String类型

  学生和籍贯之间存在映射关系

  映射关系用Map表示

  键:Student

  值:籍贯

  

 * 

 * */

public class Test2 {

/**

 * @param args

 */

public static void main(String[] args) {

HashMap<Student,String> hm=new LinkedHashMap<Student,String>();

hm.put(new Student("aa",23),"保定");

hm.put(new Student("bb",24),"廊坊");

hm.put(new Student("cc",32),"石家庄");

hm.put(new Student("dd",26),"邢台");

hm.put(new Student("ee",21),"邯郸");

//keySet

/*Set<Student> set=hm.keySet();

Iterator<Student> it=set.iterator();

while(it.hasNext()){

Student s=it.next();

String address=hm.get(s);

System.out.println(s.getName()+"..."+s.getAge()+".."+address);

}*/

//entrySet

Set<Map.Entry<Student,String>> entrys=hm.entrySet();

Iterator<Map.Entry<Student,String>> it1=entrys.iterator();

while(it1.hasNext()){

Map.Entry<Student,String> entry=it1.next();

System.out.println(entry.getKey().getName()+"..."+entry.getValue());

}

}

}

你可能感兴趣的:(java中的简单注解、集合的简单复习)