• Java注解


    Java注解用于为Java代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java注解是从Java5开始添加到Java的。
    1- 什么是注解?
    1.1- 编译指令
    1.2- 编译时指令
    1.3- 运行时指令
    2- 内置注解
    2.1- @Deprecated
    2.2- @Override
    2.3- @SuppressWarnings
    3- 编写注解
    3.1- 你的第一个注解
    3.2- 注解与元素值
    3.3- @Retention & @Target
    3.4- Annotation & Reflection
    4- 注解处理工具(高级知识)

    1- 什么是注解

    Java注解用于为Java代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java注解是从Java5开始添加到Java的。
    Java注解通常用于以下目的:
    1. 编译器指令
    2. 编译时指令
    3. 运行时指令

    1.1- 编译指令

    Java有3个内置的注解,你可以用它来发出指令到Java编译器。
    • @Deprecated
    • @Override
    • @SuppressWarnings
    这些注释后面详细文件中会解释。

    1.2- 编译时指令

    当你创建建软件项目时,Java注释可以在编译时使用。构建过程包括生成的源代码,编译源文件,生成XML文件(例如部署描述符),包装编译代码和文件到一个JAR文件等。构建软件通常是通过像Apache Ant组织的Apache Maven的自动构建工具完成。 构建工具可以扫描你的Java代码指定的注解并生成源代码或基于这些注解其他文件。

    1.3- 运行时指令

    通常情况下,Java注解中不存在于编译后的Java代码。这是可能的,但是,定义自己的注解是在运行时可用。这些注解然后可以通过Java反射访问,并用于发出指令到您的程序,或者一些第三方API。

    2- 内置注解

    Java有3个重要注解可用:
    • @Deprecated
    • @Override
    • @SuppressWarnings

    2.1- @Deprecated

    这是用来注解过时的东西,如类或方法的注解; 最好我们不应该再使用它。
    如果你使用的东西过时,编译器会通知您应该使用的另一种方式。
    或IDE编程像Eclipse,它也给你显示出可视化通知。
    • DeprecatedMethodDemo.java
    package com.yiibai.tutorial.ann.builtin;
    
    import java.util.Date;
    
    public class DeprecatedMethodDemo {
    
       /**
        * @deprecated replaced by {@link #todo(String,Date)}
        */
       @Deprecated
       public void todoJob(String jobName) {
           System.out.println("Todo " + jobName);
       }
    
       public void todo(String jobName, Date atTime) {
           System.out.println("Todo " + jobName + " at " + atTime);
       }
    
       public void todoNothing() {
           System.out.println("Todo Nothing");
       }
    
       public static void main(String[] args) {
    
           DeprecatedMethodDemo obj = new DeprecatedMethodDemo();
    
           obj.todoJob("Java coding");
    
           obj.todoNothing();
       }
    }
    
    这里有图片,Eclipse将通知您:

    2.2- @Override

    @Override注解来覆盖超类方法在方法使用。如果这个方法不超匹配的方法,编译器就会给你一个错误。

    要覆盖超类的方法而使用 @Override 注解是没有必要的。如仍然使用它,也是个好主意。万一有人改变超类中的重写方法名称,子类的方法将不再覆盖它。 没有@Override注释,你不好找到问题答案。有了@Override注解,编译器会告诉你,在子类中的方法不重写超类的任何方法。
    下面我们来看一个例子:
    • Job.java
    package com.yiibai.tutorial.ann.builtin;
    
    public class Job {
    
        // This is method of Job class.
        public String getName() {
            return null;
        }
    
    }
    
    • JavaCoding.java
    ckage com.yiibai.tutorial.ann.builtin;
    
    public class JavaCoding extends Job {
    
     
        // This method is overridden method getName() of the superclass.
        // @Override not required to write on this method.
        // But it is necessary if someone changed the name of the method getName()
        // in parent class, an error message will tell you.
        @Override
        public String getName() {
            return "Java Coding";
        }
    }
     
    
    这里是Java编译器警告:

    2.3- @SuppressWarnings

    @SuppressWarnings注解使编译器抑制对某个方法的警告。例如,如果一个方法调用的方法已过时,或使一个不安全的类型转换,编译器可能会产生一个警告。您可以通过包含使用@SuppressWarnings注解代码的方法标注抑制这些警告。
    下面我们来看看一个例子:
    • SuppressWarningsDemo.java
    package com.yiibai.tutorial.ann.builtin;
    
    import java.util.Date;
    
    public class SuppressWarningsDemo {
    
       @SuppressWarnings("deprecation")
       public Date getSomeDate() {
    
           Date date = new Date(2014, 9, 25);
           return date;
       }
    
    }
    
    详见编译器警告:

    • SuppressWarningsDemo2.java
    package com.yiibai.tutorial.ann.builtin;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    public class SuppressWarningsDemo2 {
    
      public List<?> getDatas() {
          List<String> list = new ArrayList<String>();
          list.add("One");
          return list;
      }
    
      @SuppressWarnings({ "deprecation", "unused", "unchecked" })
      public void processDatas() {  
    
         
          // You use deprecated Constructor
          // Variable 'date' was created, but not used      
          Date date = new Date(2014, 9, 25);
    
          // Cast unsafe.
          // Variable 'datas' is created, but not used in the code.      
          List<String> datas= (List<String>) this.getDatas();        
      }
    
    }
    
    来自编译器的警告:

    3- 编写你自己的注解

    @interface是声明一个注释的关键字,而这个注解非常相似于接口。注解可有或没有元素。注释元素的特点:
    • 没有函数体
    • 没有函数参数
    • 返回的声明必须在一个特定的类型:
      • 基本类型 (boolean, int, float,...)
      • 枚举
      • 注解
      • 类(如:String.class)
    • 元素可以有默认值

    3.1- 你的第一个注解

    • MyFirstAnnotation.java
    package com.yiibai.tutorial.ann1;
    
    public @interface MyFirstAnnotation {
    
        // element name.
        public String name();
    
        // Element description, default value "".
        public String description() default "";  
    }
    
    注释可以用在:
    1. TYPE - 类,接口(包括注释类型)或枚举声明
    2. FIELD - 字段声明(包括枚举常量)
    3. METHOD - 方法声明
    4. PARAMETER - 参数声明
    5. CONSTRUCTOR - 构造函数声明
    6. LOCAL_VARIABLE - 局部变量声明
    7. ANNOTATION_TYPE - 注解声明
    8. PACKAGE - 包声明
    • UsingMyFirstAnnotation.java
    package com.yiibai.tutorial.ann1;
    
    @MyFirstAnnotation(name = "Some name", description = "Some description")
    public class UsingMyFirstAnnotation {
    
        // Annotation on Constructor.
        // The value of the element name is "John"
        // Value element description is "Write by John".
        @MyFirstAnnotation(name = "John", description = "Write by John")
        public UsingMyFirstAnnotation() {
    
        }
       
        // Annotation tied up method.
        // The value of the element name is "Tom"
        // Description element is not declared, it will be assigned a default value    
        @MyFirstAnnotation(name = "Tom")
        public void someMethod() {
    
        }
    
        // An Annotation on parameter of method.
        public void todo(@MyFirstAnnotation(name = "none") String job) {
    
            // An annotation on local variable.
            @MyFirstAnnotation(name = "Some name")
            int localVariable = 0;
    
        }
    
    }
    

    3.2- 注释与元素值

    注解有一个元素命名值,它有一些特点:
    • AnnWithValue.java
    package com.yiibai.tutorial.ann2;
    
    public @interface AnnWithValue {
    
     
        // Element named 'value'
        // There is a bit special when using this element.    
        public int value();
    
        // Element 'name'.    
        public String name() default "";
    
    }
    
    • UsingAnnWithValue.java
    package com.yiibai.tutorial.ann2;
    
    public class UsingAnnWithValue {
    
        @AnnWithValue(name = "Name1", value = 100)
        public void someMethod1() {
    
        }
       
        // Initialize the elements of Annotation in the usual way.
        // Element 'name' using default.
        @AnnWithValue(value = 100)
        public void someMethod2() {
    
        }
    
     
        // With element 'value', you can just write out the value of it.    
        @AnnWithValue(100)
        public void someMethod3() {
    
        }
    }
    

    3.3- @Retention & @Target

    @Retention & @Target 是Java 的两个可用的注解。

    @Retention: 使用时要注意一些注解的存在层次。
    特别是,有3个级别的所提到东西存在要注意:
    1. RetentionPolicy.SOURCE: 存在于源代码,并编译器自由识别。
    2. RetentionPolicy.CLASS: 它的存在是由编译器识别,但不是由虚拟机在运行时。
    3. RetentionPolicyRUNTIME: 达到存在的最高级别,由编译器和由虚拟机在运行时确定的。
    @Target: 在使用时要注意另一个注解及其使用范围。
    1. ElementType.TYPE - 附在类,接口,枚举,注解的声明。
    2. ElementType.FIELD - 附在字段的声明和枚举常量。
    3. ElementType.METHOD - 附在方法的声明。
    4. ElementType.PARAMETER - 附在参数的声明
    5. ElementType.CONSTRUCTOR - 附在构造函数的声明
    6. ElementType.LOCAL_VARIABLE - 附在局部变量
    7. ElementType.ANNOTATION_TYPE - 附在注释的声明
    8. ElementType.PACKAGE - 附在包的声明
    • AnnFM.java
    package com.yiibai.tutorial.ann3;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    // Annotation are to be discarded by the compiler.
    @Retention(value = RetentionPolicy.SOURCE)
    
    // AnnFM will only be used on FIELD or  METHOD.
    @Target(value = { ElementType.FIELD, ElementType.METHOD })
    public @interface AnnFM {
    
    }
    
    • UsingAnnFM.java
    package com.yiibai.tutorial.ann3;
    
    public class UsingAnnFM {
    
        // AnnFM will only be used on FIELD or  METHOD.
        @AnnFM
        protected int someField = 100;
    
        // AnnFM will only be used on FIELD or  METHOD.
        @AnnFM
        public void someMethod() {
    
        }
    
    }
    

    3.4- 注解与反射

    Java反射通过一些注解的东西可以识别像类,字段,方法。当然它只能使用@Retention(RetentionPolicy.RUNTIME) 识别注解
    下面的例子说明一个程序读取原始的Java文件,并创建HTML文件的注释。每个类相当于一个HTML文件。

    • AnnHtmlUL.java
    package com.yiibai.tutorial.ann4;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
     
    // Using for Class, interface, annotation, enum.
    @Target(value = { ElementType.TYPE })
    
     
    // Simulating the <UL> in HTML.
    public @interface AnnHtmlUL {
    
        public String border() default "border:1px solid blue;";
    }
    
    • AnnHtmlLI.java
    package com.yiibai.tutorial.ann4;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value = { ElementType.FIELD,ElementType.METHOD })
    
     
    // Simulating the <LI> in HTML.
    public @interface AnnHtmlLI {
    
        public String background();
    
        public String color() default "red";
    }
    
    • DocumentClass.java
    package com.yiibai.tutorial.ann4;
    
    @AnnHtmlUL(border = "1px solid red")
    public class DocumentClass {
    
        private String author;
    
        @AnnHtmlLI(background = "blue", color = "black")
        public String getDocumentName() {
            return "Java Core";
        }
    
        @AnnHtmlLI(background = "yellow")
        public String getDocumentVersion() {
            return "1.0";
        }
    
        @AnnHtmlLI(background = "green")
        public void setAuthor(String author) {
            this.author = author;
        }
    
        @AnnHtmlLI(background = "red", color = "black")
        public String getAuthor() {
            return author;
        }
        
        // This method is not annotated
        public float getPrice()  {
            return 100;
        }
    
    }
    
    • HtmlGenerator.java
    package com.yiibai.tutorial.ann4;
    
    import java.lang.reflect.Method;
    
    public class HtmlGenerator {
    
        public static void main(String[] args) {
    
            Class<?> clazz = DocumentClass.class;
    
             // Check if this class is annotated by Annotation AnnHtmlUL or not.
            boolean isHtmlUL = clazz.isAnnotationPresent(AnnHtmlUL.class);
    
            StringBuilder sb = new StringBuilder();
            if (isHtmlUL) {
                // Get the AnnHtmlUL annotation on this class.
                AnnHtmlUL annUL = clazz.getAnnotation(AnnHtmlUL.class);
    
                sb.append("<H3>" + clazz.getName() + "</H3>");
                sb.append("
    ");
    
    
                // Get the value of the element 'border'.
                String border = annUL.border();
    
                sb.append("<UL style='border:" + border + "'>");
                
                // Add new line
                sb.append("
    ");
    
                Method[] methods = clazz.getMethods();
    
                for (Method method : methods) {
                    // Check if this method is annotated by Annotation AnnHtmlLI or not.
                    if (method.isAnnotationPresent(AnnHtmlLI.class)) {
    
                        // Get the annotation
                        AnnHtmlLI annLI = method.getAnnotation(AnnHtmlLI.class);
    
                        // Get the values of elements.
                        String background = annLI.background();
                        String color = annLI.color();
    
                        sb.append("<LI style='margin:5px;padding:5px;background:"
                                + background + ";color:" + color + "'>");
                        sb.append("
    ");
                        sb.append(method.getName());
                        sb.append("
    ");
                        sb.append("</LI>");
                        sb.append("
    ");
                    }
                }
                sb.append("</UL>");
            }
            writeToFile(clazz.getSimpleName() + ".html", sb);
        }
       
        // Write to Console (Or file)
        private static void writeToFile(String fileName, StringBuilder sb) {
            System.out.println(sb);
        }
    
    }
    
    运行示例的结果:

    写入HTML文件:

    4- 注解处理工具(高级知识)

    这种情况是:
    您可以创建自己的注解,并在Java应用程序中使用它们。您将使用这些注解规则。要Java编译器来通知应用错误的规则,在编译时的错误。
    如果使用Eclipse编写代码,Eclipse将通知用户错误的一些正确用法。
  • 相关阅读:
    java socket HTTPClient GET
    Spring的JdbcTemplate使用update或insert操作的三种使用例子
    windows XP 解决QQ和360软件冲突的办法
    J2EE 应用服务器集群常用方法
    javaeye被关闭了 被政 府和谐感
    P6SPY(JDBC SQL拦截)的安装和使用
    让QQ与360并存,不卸载360正常使用QQ
    Spring2.5注解(标注)学习笔记(使用annotation代替XML)
    centos vnc配置
    HTTP协议内容具体含义
  • 原文地址:https://www.cnblogs.com/judewu/p/7929003.html
Copyright © 2020-2023  润新知