Java注解机制基础学习

一、注解概念

了解java注解,你就必须先了解元数据的概念。

元数据:

(MetaData)和业务逻辑无关,描述数据的数据。(Data about other data)

注解目的:

一是方便,二是代码更加简洁。

什么是注解?

用一个词就可以描述注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。比如,下面这段代码:

@Override
public String toString() {
    return "This is String Representation of current object.";
}

上面的代码中,重写了toString()方法并使用了@Override注解。但是,即使我不使用@Override注解标记代码,程序也能够正常执行。那么,该注解表示什么?这么写有什么好处吗?事实上,@Override告诉编译器这个方法是一个重写方法(描述方法的元数据),如果父类中不存在该方法,编译器便会报错,提示该方法没有重写父类中的方法。如果我不小心拼写错误,例如将toString()写成了toStrring(){double r},而且我也没有使用@Override注解,那程序依然能编译运行。但运行结果会和我期望的大不相同。现在的你了解了什么是注解,并且使用注解有助于阅读程序。

Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符。它是一种由JSR-175标准选择用来描述元数据的一种工具。

为什么要引入注解?

使用Annotation之前(甚至在使用之后),XML被广泛的应用于描述元数据。不知何时开始一些应用开发人员和架构师发现XML的维护越来越糟糕了。他们希望使用一些和代码紧耦合的东西,而不是像XML那样和代码是松耦合的(在某些情况下甚至是完全分离的)代码描述。如果你在Google中搜索“XML vs. annotations”,会看到许多关于这个问题的辩论。最有趣的是XML配置其实就是为了分离代码和配置而引入的。上述两种观点可能会让你很疑惑,两者观点似乎构成了一种循环,但各有利弊。下面我们通过一个例子来理解这两者的区别。

假如你想为应用设置很多的常量或参数,这种情况下,XML是一个很好的选择,因为它不会同特定的代码相连。如果你想把某个方法声明为服务,那么使用Annotation会更好一些,因为这种情况下需要注解和方法紧密耦合起来,开发人员也必须认识到这点。

另一个很重要的因素是Annotation定义了一种标准的描述元数据的方式。在这之前,开发人员通常使用他们自己的方式定义元数据。例如,使用标记interfaces,注释,transient关键字等等。每个程序员按照自己的方式定义元数据,而不像Annotation这种标准的方式。

目前,许多框架将XML和Annotation两种方式结合使用,平衡两者之间的利弊。

注解的语法

语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解:

  • @Override,表示当前的方法定义将覆盖超类中的方法。
  • @Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。
  • @SuppressWarnings,关闭不当编译器警告信息。

上面这三个注解多少我们都会在写代码的时候遇到。Java还提供了4中注解,专门负责新注解的创建。

1.@Target

表示该注解可以用于什么地方,可能的ElementType参数有:

CONSTRUCTOR:构造器的声明

FIELD:域声明(包括enum实例)

LOCAL_VARIABLE:局部变量声明

METHOD:方法声明

PACKAGE:包声明

PARAMETER:参数声明

TYPE:类、接口(包括注解类型)或enum声明

2.@Retention

定义该注解的生命周期。可选的RetentionPolicy参数包括:

SOURCE:注解将被编译器丢弃

CLASS:注解在class文件中可用,但会被VM丢弃

RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息

3.@Document

将注解包含在Javadoc中

4.@Inherited

允许子类继承父类中的注解

二、举个例子:

定义一个注解的方式:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}

除了@符号,注解很像是一个接口。定义注解的时候需要用到元注解,上面用到了@Target和@RetentionPolicy,它们的含义在上面的表格中已近给出。

在注解中一般会有一些元素以表示某些值。注解的元素看起来就像接口的方法,唯一的区别在于可以为其制定默认值。没有元素的注解称为标记注解,上面的@Test就是一个标记注解。
注解的可用的类型包括以下几种:所有基本类型、String、Class、enum、Annotation、以上类型的数组形式。元素不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略“value=”,直接写需要的值即可。
下面看一个定义了元素的注解。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public String id();
    public String description() default "no description";
}

定义了注解,必然要去使用注解。

public class PasswordUtils {
       @UseCase(id = 47, description = "Passwords must contain at least one numeric")
       public boolean validatePassword(String password) {
           return (password.matches("\\w*\\d\\w*"));
       }

       @UseCase(id = 48)
       public String encryptPassword(String password) {
           return new StringBuilder(password).reverse().toString();
      }
}

使用注解最主要的部分在于对注解的处理,那么就会涉及到注解处理器。

从原理上讲,注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理。

public static void main(String[] args) {
     List<Integer> useCases = new ArrayList<Integer>();
     Collections.addAll(useCases, 47, 48, 49, 50);
     trackUseCases(useCases, PasswordUtils.class);
 }

 public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
     for (Method m : cl.getDeclaredMethods()) {
         UseCase uc = m.getAnnotation(UseCase.class);
         if (uc != null) {
             System.out.println("Found Use Case:" + uc.id() + " "
                         + uc.description());
             useCases.remove(new Integer(uc.id()));
         }
     }
     for (int i : useCases) {
         System.out.println("Warning: Missing use case-" + i);
     }
}

Found Use Case:47 Passwords must contain at least one numeric

Found Use Case:48 no description

Warning: Missing use case-49

Warning: Missing use case-50

上面的三段代码结合起来是一个跟踪项目中用例的简单例子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java基础需要学习的知识包括但不限于以下内容: 1. Java的基本语法,如变量、数据类型、运算符、条件语句、循环语句等; 2. 面向对象编程的概念,如类、对象、继承、多态等; 3. Java中的异常处理机制,如try-catch语句、throw语句等; 4. Java中的集合框架,如List、Set、Map等; 5. IO流和文件操作; 6. 网络编程和Socket编程; 7. 多线程编程。 除了以上基础知识外,还可以学习Java的高级特性,如反射、注解、泛型等,以及常用的框架,如Spring、Hibernate等。同时,也可以学习Java在各种应用场景中的应用,如Web开发、移动应用开发、大数据处理等。 ### 回答2: 学习Java基础知识是成为一名优秀的Java开发人员的必要步骤。下面是一些需要学习的主要知识点: 1. Java语言基础:包括Java的历史、特性、语法、标识符、变量、数据类型、运算符等。这些是理解和编写Java程序的基础。 2. 面向对象编程(OOP):理解面向对象编程的概念和原则,例如封装、继承和多态。学习如何创建和使用类、对象和方法。 3. 控制流程:了解条件语句(if-else、switch)、循环语句(for、while、do-while)和跳转语句(break、continue)的使用方法。 4. 数组和集合:学习如何创建和使用数组,并了解常见的数据结构例如ArrayList、LinkedList和HashMap等。这些是处理大量数据的重要工具。 5. 异常处理:学习如何检测、抛出和捕获异常。理解处理异常的重要性,以及如何有效地处理错误和异常。 6. 输入输出(I/O)操作:了解如何读取和写入文件、处理用户输入和输出。学习如何使用Java的I/O类进行文件和流的操作。 7. 多线程编程:了解多线程的概念、实现和管理。学习如何创建和启动线程,并掌握同步和互斥的概念。 8. JDBC和数据库操作:学习如何连接和操作关系型数据库,如MySQL、Oracle等。了解SQL语句的基本语法,以及如何使用Java中的JDBC API进行数据库操作。 9. 常用类库:学习使用Java的常用类库,如日期和时间类、字符串处理类、正则表达式类等。了解常用类库的功能和使用方法,提高编程效率。 除了上述知识点,还需要不断练习编程,进行项目实战,提升自己的实际应用能力。同时还可以通过阅读相关的书籍和参与开发社区的讨论,来不断拓展和深化自己的Java基础知识。 ### 回答3: Java是一种广泛应用的编程语言,作为学习Java基础的人,需要掌握以下几方面的知识。 首先,Java语言的基本语法是学习的重点,包括变量的声明与使用、数据类型、运算符、控制语句(if-else、for、while等)、数组、字符串等。掌握这些基本语法是理解Java程序的基础。 其次,面向对象思想是Java的核心。需要学习类与对象的概念,如何定义和使用类、继承、封装、多态等。掌握面向对象思想可以让程序更加模块化、可维护和扩展。 此外,Java的异常处理机制也是需要掌握的重要知识。学习如何使用try-catch语句处理异常,如何创建自定义异常类以及如何处理异常的传递和捕获。合理的异常处理可以提高程序的健壮性和可靠性。 最后,Java的标准库也是需要学习的内容,例如输入输出流、集合类、多线程等。了解这些标准库的用法可以提高编程效率,并且可以更好地完成各种编程任务。 综上所述,学习Java基础需要掌握的知识包括基本语法、面向对象思想、异常处理机制以及Java标准库的使用。通过学习这些知识,可以打下扎实的编程基础,并为进一步深入学习Java高级特性和应用开发打下坚实的基础

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值