java注解

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()+"(
");
			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()+"),
");
				}
			}
			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();
		}
	}
}

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

  

态度决定高度,细节决定成败,
原文地址:https://www.cnblogs.com/lxk2010012997/p/5063706.html