Annotation(注解)是JDK1.5及以后版本引入,目前大部分框架(如Spring,Android ButterKnife,OrmLite,Retrofit等)都使用了注解简化代码并提高编码的效率。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
元注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
- @Target,用来约束注解可以应用的地方(如方法、类或字段),其中ElementType是枚举类型 当注解未指定Target值时,则此注解可以用于任何元素之上,多个值使用{}包含并用逗号隔开,如下:
@Target(value={ElementType.CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
- @Retention,定义该注解的生命周期。
RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override,@SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。 - @Documented,一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
- @Inherited,定义该注释和子类的关系
实例
image.png注解model
image.png
获取注解
image.png
生成sql语句
CREATE TABLE IF NOT EXISTS CustomTable(UserCustomList BLOB ,datatype INTEGER ,resverT TEXT
获取注解的过程中用反射机制。如果你熟悉反射代码,就会知道反射可以提供类名、方法和实例变量对象。所有这些对象都有getAnnotation()这个方法用来返回注解信息。我们需要把这个对象转换为我们自定义的注释(使用 instanceOf()检查之后),同时也可以调用自定义注释里面的方法
-
获取方法中参数注解
image.png
image.png
image.png - 编译时注解
自定义注解,实现findViewById
package com.xxx.app.utils.annotions;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by on 2017/4/27.
* model转换
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ColumnsName {
String fieldName() default "";
}
package com.xxx.app.utils.annotions;
import com.xxx.app.common.log.LogUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by on 2017/4/28.
* 反射工具类
* 目前主要提供model转换
*/
public class ReflectUtils {
private static final String TAG = ReflectUtils.class.getSimpleName();
/**
* 两个不同类型的 通过注解赋值
* origin 中有注解的属性值 拷贝到destination中
*
* @param destination 目标model
* @param origin 数据源model 注解名称和destination中的字段一致
* @param <T>
* @return 是否有赋值失败
*/
/**
* 两个不同类型的
*
* @param destination
* @param origin
* @param <T>
*/
public static <T> boolean mergeAnnotion2Object(T destination, T origin) {
boolean isSuccess = true;
if (origin == null || destination == null)
return false;
List<Field> originList = getDeclaredFields(origin);
List<Field> desList = getDeclaredFields(destination);
for (Field originField : originList) {
for (Field desField : desList) {
ColumnsName annotation = originField.getAnnotation(ColumnsName.class);
if (desField.getName().equals(originField.getName())
|| (annotation != null && desField.getName().equals(annotation.fieldName()))) {
try {
desField.setAccessible(true);
Object value = originField.get(origin);
if (null != value) {
desField.set(destination, value);
}
desField.setAccessible(false);
} catch (Exception e) {
isSuccess = false;
}
continue;
}
}
}
return isSuccess;
}
/**
* 反向
* 赋值到destination
*
* @param origin 无注解
* @param destination 有注解
* @param <T>
* @return
*/
public static <T> boolean merge2AnnotionObject(T destination, T origin) {
boolean isSuccess = true;
if (destination == null || origin == null)
return false;
List<Field> originList = getDeclaredFields(origin);
List<Field> desList = getDeclaredFields(destination);
for (Field originField : originList) {
for (Field desField : desList) {
ColumnsName annotation = desField.getAnnotation(ColumnsName.class);
if (desField.getName().equals(originField.getName())
|| (annotation != null && originField.getName().equals(annotation.fieldName()))) {
try {
desField.setAccessible(true);
Object value = originField.get(origin);
if (null != value) {
desField.set(destination, value);
}
desField.setAccessible(false);
} catch (Exception e) {
isSuccess = false;
}
continue;
}
}
}
return isSuccess;
}
private static <T> List<Field> getDeclaredFields(T origin) {
Class<?> clazz = origin.getClass();
List<Field> list = new ArrayList<>();
for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
list.addAll(Arrays.asList(clazz.getDeclaredFields()));
}
return list;
}
/**
* 两个不同类型的
* origin 中的属性值拷贝到destination中
*
* @param destination
* @param origin
* @param <T>
*/
public static <T> boolean mergeDiffObject(T destination, T origin) {
boolean isSuccess = true;
if (origin == null || destination == null)
return false;
Field[] fields = origin.getClass().getDeclaredFields();
Field[] desFields = destination.getClass().getDeclaredFields();
int length = fields.length;
int desLength = desFields.length;
for (int i = 0; i < length; i++) {
for (int j = 0; j < desLength; j++) {
if (fields[i].getName().equals(desFields[j].getName())) {
try {
desFields[j].setAccessible(true);
Object value = fields[i].get(origin);
if (null != value) {
desFields[j].set(destination, value);
}
desFields[i].setAccessible(false);
} catch (Exception e) {
isSuccess = false;
LogUtils.i(TAG, "mergeDiffObject:{}", e.getMessage());
}
continue;
}
}
}
return isSuccess;
}
/**
* 两个相同类型的obj
*
* @param origin
* @param destination
* @param <T>
*/
public static <T> boolean mergeObject(T origin, T destination) {
boolean isSuccess = true;
if (origin == null || destination == null)
return false;
if (!origin.getClass().equals(destination.getClass()))
return false;
Field[] fields = origin.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
try {
fields[i].setAccessible(true);
Object value = fields[i].get(origin);
if (null != value) {
fields[i].set(destination, value);
}
fields[i].setAccessible(false);
} catch (Exception e) {
isSuccess = false;
LogUtils.i(TAG, "mergeDiffObject:{}", e.getMessage());
}
}
return isSuccess;
}
}
网友评论