你的位置:首页 > 软件开发 > Java > Java注解一谈

Java注解一谈

发布时间:2016-05-24 17:00:16
阅读目录1.元注解2.自定义注解3.注解处理器android注解框架解析我们经常会在java代码里面看到:“@Override”,“@Target”等等样子的东西,这些是什么?在java里面它们是&a ...

阅读目录

  • 1.元注解
  • 2.自定义注解
  • 3.注解处理器
  • android注解框架解析
package com.joyfulmath.jvmexample.annnotaion;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @author deman.lu * @version on 2016-05-23 13:36 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface FruitName {  String value() default "";}
Java注解一谈

首先,一个注解一般需要2个元注解修饰:

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)
package com.joyfulmath.jvmexample.annnotaion;import com.joyfulmath.jvmexample.TraceLog;/** * @author deman.lu * @version on 2016-05-23 13:37 */public class Apple {  @FruitName("Apple")  String appleName;  public void displayAppleName()  {    TraceLog.i(appleName);  }}
Java注解一谈

这段代码的log:

05-23 13:39:38.780 26792-26792/com.joyfulmath.jvmexample I/Apple: displayAppleName: null [at (Apple.java:16)]

没有赋值成功,为什么?应为注解的“Apple”到底怎么赋值该filed,目前编译器还不知道则怎么做呢。

回到顶部
package com.joyfulmath.jvmexample.annnotaion;import com.joyfulmath.jvmexample.TraceLog;import java.lang.reflect.Field;/** * @author deman.lu * @version on 2016-05-23 14:08 */public class FruitInfoUtils {  public static void getFruitInfo(Class<?> clazz)  {    String fruitNameStr = "";    Field[] fields = clazz.getDeclaredFields();    for(Field field:fields)    {      if(field.isAnnotationPresent(FruitName.class))      {        FruitName fruitName = field.getAnnotation(FruitName.class);        fruitNameStr = fruitName.value();        TraceLog.i(fruitNameStr);      }    }  }}
Java注解一谈

 

这是注解的一般用法。

 

回到顶部
package butterknife;import android.support.annotation.StringRes;import java.lang.annotation.Retention;import java.lang.annotation.Target;import static java.lang.annotation.ElementType.FIELD;import static java.lang.annotation.RetentionPolicy.CLASS;/** * Bind a field to the specified string resource ID. * <pre><code> * {@literal @}BindString(R.string.username_error) String usernameErrorText; * </code></pre> */@Retention(CLASS) @Target(FIELD)public @interface BindString { /** String resource ID to which the field will be bound. */ @StringRes int value();}
Java注解一谈

BindString,只有一个参数,value,也就是赋值为@StringRes.

同上,上面是注解定义和使用的地方,但是真正解释注解的地方如下:ButterKnifeProcessor

private Map<TypeElement, BindingClass> findAndParseTargets(RoundEnvironment env)
  // Process each @BindString element.  for (Element element : env.getElementsAnnotatedWith(BindString.class)) {   if (!SuperficialValidation.validateElement(element)) continue;   try {    parseResourceString(element, targetClassMap, erasedTargetNames);   } catch (Exception e) {    logParsingError(element, BindString.class, e);   }  }
Java注解一谈

找到所有BindString注解的元素,然后开始分析:

Java注解一谈
 @Override public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) {  Map<TypeElement, BindingClass> targetClassMap = findAndParseTargets(env);  for (Map.Entry<TypeElement, BindingClass> entry : targetClassMap.entrySet()) {   TypeElement typeElement = entry.getKey();   BindingClass bindingClass = entry.getValue();   try {    bindingClass.brewJava().writeTo(filer);   } catch (IOException e) {    error(typeElement, "Unable to write view binder for type %s: %s", typeElement,      e.getMessage());   }  }  return true; }
Java注解一谈

这就是注解框架启动的地方,一个独立的进程。具体细节本文不研究,只需清除,这里是框架驱动的地方。

从上面的信息已经清除,所有的注解信息都存放在targetClassMap 里面。

上面标红的代码,应该是注解框架的核心之处。

自从Java SE5开始,Java就引入了apt工具,可以对注解进行预处理,Java SE6,更是支持扩展注解处理器,

并在编译时多趟处理,我们可以使用自定义注解处理器,在Java编译时,根据规则,生成新的Java代码。

Java注解一谈

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:Java注解一谈

关键词:JAVA

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。