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

java注解简单讲解及应用

2016-05-27 15:50 507 查看
1、java中常见的注解

jdk自带的注解:

                @Override    覆盖父类方法

@Override
public String name() {
return null;
}


当发现父类的方法定义的有些问题,但是又不能删除,因为有些地方还在

调用这个接口则:

                @Deprecated   表示方法已经过时

父类中设置方法过时:
@Deprecated
public void sing();


                @Suppvisewarnings  忽视方法过时的警告

当测试类调用时,会出现方法过时的警告,点击感叹号,添加忽视过时:
@SuppressWarnings("deprecation")
public void sing(){
Person p = new child();
p.sing();
}


2、常见的第三方注解:

Spring :

                @Autowired

                @Service

                @Repository

Mybatis :

 

                @InterProvider

                @UpdateProvider

          

                @Options

              

  
3、注解的分类:

                -->源码注解

                注解只在源码中存在,编译成.class文件就没了

                -->编译时注解

                注解在源码和.class文件中存在

                例如:@Override告诉编译器覆盖父类方法,然后进行编译

                -->运行时注解

                注解在运行阶段还起作用,影响运行逻辑          

                例如:@Autowired运行时把成员变量装配进来

                元注解:给注解进行的注解

4、自定义注解:

   声明:
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{// 使用@interface关键字定义注

解
String desc();//成员以无参无异常方式声明

String author();

int age() default 18;//可以用default为成员指定一个默认值

}


    元注解:
//注解作用域(构造方法、局部变量、方法声明、包声明类接口等)
@Target({ElementType.METHOD,ElementType.TYPE})
//注解的生命周期(源码、编译时、运行时)
@Retention(RetentionPolicy.RUNTIME)
//表示注解允许子类继承
@Inherited
//表示生成javadoc时会包含注解
@Documented


    使用自定义注解:
@Description(desc="zy",author="boy",age=18)
public String eyeColor(){
return "red";
}
    这样,@Description注解就在eyeColor()方法上使用

5、解析注解:

   通过反射获取类、函数或成员上的运行时注解信息,从而动态控制程序 

  运
4000
行的逻辑.

//1、使用类加载器加载类
try {
Class c = Class.forName

("com.ann.test.child");
//2、找到类上面的注解(判断指定类上是否存

在Description这个注解)
boolean isExist = c.isAnnotationPresent

(Description.class);
if(isExist){
//3、拿到注解实例
Description d = (Description)

c.getAnnotation(Description.class);
System.out.println(d.value());
}
//4、找到方法上的注解
//首先遍历所有的方法
Method[] ms = c.getMethods();
for (Method m : ms) {
//判断是否有注解
boolean isMExist =

m.isAnnotationPresent(Description.class);
if (isMExist) {
//如果存在则使用注解
Description md =

(Description)m.getAnnotation(Description.class);
System.out.println

(md.value());
}

}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}


     注解的继承:

          父类中添加注解,子类中删除原有注解

          此时还是用上面的解析方式对子类进行注解解析
          此时运行不输出任何东西

          原因是:  @Inherited对于接口继承不起作用

          所以要把Person改为类,而不是接口

          child类中改为extends

          运行 --> 打印出类上的注解,而不打印方法上的注解

          所以注解只继承类上的注解,而不继承方法上的注解

6、项目实现:

需求:对象设置好要查询的条件,调用query()后返回对应的sql语句

Filter.java类:(对应了数据库表中各个字段)

   
package com.zy.test;

@Table("user")
public class Filter {

@Column("id")
private int id;

@Column("user_name")
private String userName;

@Column("nick_name")
private String nickName;

@Column("age")
private int age;

@Column("city")
private String city;

@Column("email")
private String email;

@Column("mobile")
private String mobile;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getNickName() {
return nickName;
}

public void setNickName(String nickNameString) {
this.nickName = nickNameString;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getMobile() {
return mobile;
}

public void setMobile(String mobile) {
this.mobile = mobile;
}

}


Test实现类:(实现配置好查询条件,调用query返回sql)

package com.zy.test;

public class Test {

public static void main(String[] args) {

Filter f1 = new Filter();
f1.setId(10);//查询id为10的用户

Filter f2 = new Filter();
f2.setUserName("lucy");//模糊查询用户名为lucy的用

户

Filter f3 = new Filter();
f3.setEmail

("zy@sina.com,zy@163.com,888888@qq.com");//查询邮箱为其中任意一个

的用户

//调用query进行查询
String sql1 = query(f1);
String sql2 = query(f2);
String sql3 = query(f3);

System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);

}

private static String query(Filter f){
return null;
}

}


对Filter类进行添加@Table和@Column两个注解之后,接下来对这两个注解

进行定义:(这里定义注解将对象与数据库中的表对应起来)

Table.java:(设置一个参数为表名,作用域为类或接口)

Column.java:(设置一个参数为列名,作用域为参数)

 

package com.zy.test;

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();

}


package com.zy.test;

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

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

String value();

}


Test.java中query()方法的实现:(注意这里字段值有String和int类型,所以要定义为 Object类型)

   

      
package com.zy.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;

public class Test {

public static void main(String[] args) {

Filter f1 = new Filter();
f1.setId(10);//查询id为10的用户

Filter f2 = new Filter();
f2.setUserName("lucy");//查询用户名为lucy的用户
f2.setAge(19);

Filter f3 = new Filter();
f3.setEmail

("zy@sina.com,zy@163.com,888888@qq.com");//查询邮箱为其中任意一个

的用户

//调用query进行查询
String sql1 = query(f1);
String sql2 = query(f2);
String sql3 = query(f3);

System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);

}

private static String query(Filter f){

StringBuilder sb = new StringBuilder();

//1、获取到class
Class c = f.getClass();

//2.通过注解获取到table的名字
boolean exists = c.isAnnotationPresent

(Table.class);
if (!exists) {
return null;
}
Table t = (Table)c.getAnnotation(Table.class);
String tableName = t.value();
sb.append("select * from ").append

(tableName).append(" where 1=1 ");
//遍历所有的字段
Field[] fArray = c.getDeclaredFields();
for (Field field : fArray) {
//4.处理每个字段对应的sql
//4.1 拿到字段名
boolean fExists = field.isAnnotationPresent

(Column.class);
if (!fExists) {//如果不是数据库字段
continue;
}
Column column = (Column)field.getAnnotation

(Column.class);
String columnNameString = column.value();
//4.2 拿到字段的值(通过反射取得get方法的名字,然

后通过反射区调用这个方法,就取得字段值)
String filedName = field.getName();
//把get加上字段名首字母大写

filedName.substring(0, 1).toUpperCase(),把首字母之后的名字内容拼

装上filedName.substring(1),就拼装成get方法
String getMethodName = "get" +

filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
//通过反射获取对应方法
Object fieldValue = null;
try {
Method getMethod = c.getMethod

(getMethodName);
//反射调用此方法后获得字段值
fieldValue = getMethod.invoke(f);
} catch (Exception e) {
e.printStackTrace();
}
//拼装sql
//如果字段值为空或者字段值在int类型时为0

fieldValue instanceof Integer && (Integer)fieldValue == 0,将不作

处理
if (fieldValue == null || (fieldValue instanceof

Integer && (Integer)fieldValue == 0)) {
continue;
}
sb.append("and ").append(filedName);
if (fieldValue instanceof String) {
//如果是包含三个邮箱的查询,即包含逗号
if (((String) fieldValue).contains(","))

{
String[] value =

((String) fieldValue).split(",");
sb.append("in(");
for (String v : value) {
sb.append

("'").append(v).append("'").append(",");
}
//把最后一个逗号删掉
sb.deleteCharAt

(sb.length()-1);
sb.append(")");
}else{

sb.append("=").append

("'").append(fieldValue).append("'");
}
}
else if (fieldValue instanceof Integer) {
sb.append("=").append

(fieldValue);
}
}

return sb.toString();

}

}


现在如果有第二张表(Department.java),也需要这样的方式进行sql生成

则只需要在对应对象中添加@Table和@Column注解即可

Department.java:

package com.zy.test;

@Table("department")
public class Department {

@Column("id")
private int id;

@Column("name")
private String name;

@Column("leader")
private String leader;

@Column("number")
private int number;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLeader() {
return leader;
}

public void setLeader(String leader) {
this.leader = leader;
}

public int getNumber() {
return number;
}

public void setNumber(int number) {
this.number = number;
}

}


只需要把query()方法中参数改为Object,这样就所有对象添加了注解的都有效了

Department d = new Department();
d.setId(1);
d.setLeader("kkk");
d.setNumber(111);
System.out.println(query(d));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: