您的位置:首页 > 编程语言 > Java开发

java注解

2015-12-21 19:58 489 查看
java注解总结:

java注解:

1.并非程序本身,但是可以对于程序做出解释(类似注释)。

2.可以被其它程序(如:编译器等)读取。(注解信息处理流程是注解和注释的最大区别,如果没有注解信息处理流程,则注解毫无意义)

下面阐述内置注解Override、Deprecated和SuppressWarnings这三个内置注解

1.Override注解的定义,仅用于方法上,表明相应的方法是重写父类的方法得到的

/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

package java.lang;

import java.lang.annotation.*;

/**
* Indicates that a method declaration is intended to override a
* method declaration in a supertype. If a method is annotated with
* this annotation type compilers are required to generate an error
* message unless at least one of the following conditions hold:
*
* <ul><li>
* The method does override or implement a method declared in a
* supertype.
* </li><li>
* The method has a signature that is override-equivalent to that of
* any public method declared in {@linkplain Object}.
* </li></ul>
*
* @author  Peter von der Ahé
* @author  Joshua Bloch
* @jls 9.6.1.4 Override
* @since 1.5
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}


@Target和@Retention是元注解。

@Target表明注解使用的地方,其中的参数类型ElementType是个枚举类型,ElementType.METHOD表明该注解用于方法上。

@Retention表明该注解的生命周期,RetentionPolicy是枚举类型,包含SOURCE、CLASS和RUNTIME三种类型,其中SOURCE和CLASS主要用于编译期供编译器使用,RUNTIME在运行时使用,可以通过反射读取。

2.Deprecated注解,表明相应的方法、变量等不鼓励使用

/**
* A program element annotated @Deprecated is one that programmers
* are discouraged from using, typically because it is dangerous,
* or because a better alternative exists.  Compilers warn when a
* deprecated program element is used or overridden in non-deprecated code.
*
* @author  Neal Gafter
* @since 1.5
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}


这个注解同上面的注解类似在此不赘述

3.SuppressWarnings注解,用于压制警告

/**
* Indicates that the named compiler warnings should be suppressed in the
* annotated element (and in all program elements contained in the annotated
* element).  Note that the set of warnings suppressed in a given element is
* a superset of the warnings suppressed in all containing elements.  For
* example, if you annotate a class to suppress one warning and annotate a
* method to suppress another, both warnings will be suppressed in the method.
*
* <p>As a matter of style, programmers should always use this annotation
* on the most deeply nested element where it is effective.  If you want to
* suppress a warning in a particular method, you should annotate that
* method rather than its class.
*
* @since 1.5
* @author Josh Bloch
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* The set of warnings that are to be suppressed by the compiler in the
* annotated element.  Duplicate names are permitted.  The second and
* successive occurrences of a name are ignored.  The presence of
* unrecognized warning names is <i>not</i> an error: Compilers must
* ignore any warning names they do not recognize.  They are, however,
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
* <p>Compiler vendors should document the warning names they support in
* conjunction with this annotation type. They are encouraged to cooperate
* to ensure that the same names work across multiple compilers.
*/
String[] value();
}


在这个注解中包含一个参数其中参数类型为String数组,参数名称为value()(注:当只有一个参数时,推荐使用value(),这样在源文件中使用注解时不用再次填写变量名)。这个value的参数比较多可以填写deprecation表明压制使用了过时类或方法而产生的警告,unchecked表明压制执行了未检查的转换时的警告,如使用集合时未指定泛型,相应的参数还有failthrough、path、serial、finally、all

对于上面三个注解的使用:

@SuppressWarnings(value="all")
public class TestAnnotation{
@Override
public String toString(){
return "";
}
@Deprecated
public static void test(){
System.out.println("hello");
}
public static void test2(){
List list = new ArrayList();
List list2 = new ArrayList();
}
public static void main(String[] args) {
Date d = new Date();
test();
}
}


可以注意到在@SuppressWarnings中的参数名称value这个是可以省略的,因为在该注解定义中参数名定义为了value(),这是默认的。当这个参数名称不是value时,则使用时必须填写对应的参数名称。

自定义注解:

注解1

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MineAnnotation {
String studentName() default "";
int age() default 10;
int id() default -1;//-1表示不存在的意思
String[] schools();
}


注解2

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value=ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MineAnnotation2 {
String value();
}


注解的使用

package com.annotation;

public class Demo {

@MineAnnotation(studentName="hello",age=10,
schools={"西北农林科技大学","西北工业大学","北京大学","清华大学"})
public void test(){

}

@MineAnnotation2(value="aaaa")
public void test2(){

}
}


仅仅定义了注解是不够的,只起到了注释程序的作用。要想实现注解的第二个作用,还需要对于注解进行解析,定义处理注解的类。

自定义注解并实现解析(类似ORM功能):

Table注解:

package com.testAnnotation2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}


Field注解:

package com.testAnnotation2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value={ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Field {
String columnName();
String type();
int length();
}


Student实体类:

package com.testAnnotation2;

@Table("tb_student")
public class Student {
@Field(columnName="id",type="int",length=10)
private int id;
@Field(columnName="studentName",type="varchar",length=10)
private String studentName;
@Field(columnName="age",type="int",length=3)
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}


解析程序:

package com.testAnnotation2;

import java.lang.annotation.Annotation;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
* 使用反射读取注解的信息,模拟处理注解信息的流程
* @author We_lxk
*
*/
public class Demo {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.testAnnotation2.Student");
//获得类所有的有效注解
Annotation[] annotations = clazz.getAnnotations();
for(Annotation a:annotations){
System.out.println(a);
}
//获得类对应的注解
Table table = (Table) clazz.getAnnotation(Table.class);
System.out.println(table.value());
StringBuffer sb = new StringBuffer();
sb.append("create table "+table.value()+"(\n");
java.lang.reflect.Field[] fields = clazz.getDeclaredFields();
for(java.lang.reflect.Field temp:fields){
Annotation[] fieldAnnotations = temp.getDeclaredAnnotations();
System.out.println("temp:"+temp);
for(Annotation cur:fieldAnnotations){
Field curfield = temp.getAnnotation(Field.class);
System.out.println(curfield.columnName()+"--"+curfield.type()+"--"+curfield.length());
sb.append(curfield.columnName()+" "+curfield.type()+"("+curfield.length()+"),\n");
}
}
sb.setCharAt(sb.length()-2, ')');
sb.append(";");
System.out.println(sb.toString());

Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "用户名", "密码");
Statement stmt = con.createStatement();
stmt.executeUpdate(sb.toString());
stmt.close();
con.close();
System.out.println("Success!!!!!!!!!");
//			//获得类的属性的注解
//			java.lang.reflect.Field f = clazz.getDeclaredField("studentName");
//			Field field = f.getAnnotation(Field.class);
//			System.out.println(field.columnName()+"--"+field.type()+"--"+field.length());
//Map<>

//根据获得的表名,字段的信息,拼出DDL语句,然后使用JDBC生成相应的表
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


执行该解析程序会自动的在数据库中根据实体类建立相应的表。

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