因项目需要,用到反射功能,我就简单学习了一下反射,感觉不够过瘾,就是简单的通过类来获取方法名,通过方法名反射进行调用类的方法。
后来想一想,通过学习java注解来顺便学习java注解的同时进行巩固反射知识。
学习目标:通过注解和反射已经可以操作类的很多操作了,无论是对类的字段获取,类的方法获取,类的字段值获取等等操作,都能得心应手。
一个经典的例子,手打了一边,感觉对java注解和反射的理解深刻了。
例子使用场景:sql的拼接,类似与hibernate的orm一样,自动封装sql
基础数据类型:
package com.dxscx.model;
import com.dxscx.myinterface.Table;
import com.dxscx.myinterface.Column;
/**
* @Author: admin@dxscx.com
* @Time: 2016-8-12 上午9:54:16
* @Notice: What do you want to do?
* @Version: v1.0
*/
@Table("t_user")
public class User {
@Column("c_id")
private int id;
@Column("c_name")
private String name;
@Column("c_password")
private String password;
public User() {
super();
}
public User(int id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password
+ "]";
}
}
表名注解:
package com.dxscx.myinterface;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author: admin@dxscx.com
* @Time: 2016-8-9 下午5:29:51
* @Notice: What do you want to do?
* @Version: v1.0
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
public String value();
}
列名注解:
package com.dxscx.myinterface;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author: admin@dxscx.com
* @Time: 2016-8-12 上午9:51:38
* @Notice: What do you want to do?
* @Version: v1.0
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
测试程序:
package com.dxscx.test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.dxscx.model.User;
import com.dxscx.myinterface.Column;
import com.dxscx.myinterface.Table;
/**
* @Author: admin@dxscx.com
* @Time: 2016-8-12 上午10:08:41
* @Notice: What do you want to do?
* @Version: v1.0
*/
public class Test1 {
/**
* 注解的测试方法
*
* @param args
*/
public static void main(String[] args) {
User u = new User();
u.setId(1);
u.setName("test");
test(u);
}
public static void test(Object o) {
// 获取到类对象
Class c = o.getClass();
boolean status = c.isAnnotationPresent(Table.class);
if (!status) {
System.out.println("不存在类型");
return;
}
// 获取到类名(简单类名,不带包名全称的)
String classname = c.getSimpleName();
System.out.print(classname + "类对应表名:");
// 获取到类对应表名
Table t = (Table) c.getAnnotation(Table.class);
System.out.println(t.value());
// 获取所有申明的字段
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
// 判断当前字段是否是注解字段
if (field.isAnnotationPresent(Column.class)) {
continue;
}
// 拿到类字段名
String field_name = field.getName();
System.out.print(field_name + "数据库字段:");
Column column = field.getAnnotation(Column.class);
// 拿到对应字段的注解内容
System.out.println(column.value());
// 取对应字段的值
String method_name = "get"
+ field_name.substring(0, 1).toUpperCase()
+ field_name.substring(1);
System.out.print(method_name + "():");
Method m;
try {
// 通过方法名获取到方法
m = c.getMethod(method_name);
// 通过方法名反射获取对象对应字段的值
Object field_value = m.invoke(o);
System.out.println(field_value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
运行结果:
User类对应表名:t_user
id数据库字段:c_id
getId():1
name数据库字段:c_name
getName():test
password数据库字段:c_password
getPassword():null
可以看到,通过注解和反射已经可以操作类的很多操作了,无论是对类的字段获取,类的方法获取,类的字段值获取等等操作,都能得心应手。