java ⾃定义的注解类⾥⾯⼀定要有value ()⽅法吗?答案:否。
java ⾃定义注解
Java 注解是附加在代码中的⼀些元信息,⽤于⼀些⼯具在编译、运⾏时进⾏解析和使⽤,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作⽤。包含在 java.lang.annotation 包中。
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited 四种。
1.1、@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class 字节码⽂件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class 字节码⽂件中存在,但运⾏时⽆法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class 字节码⽂件中存在,在运⾏时可以通过反射获取到注解类:
实体类:[java]
01. @Retention (RetentionPolicy.RUNTIME) // 注解会在class 字节码⽂件中存在,在运⾏时可以通过反射获取到 02. @Target ({ElementType.FIELD,ElementType.METHOD})//定义注解的作⽤⽬标**作⽤范围字段、枚举的常量/⽅法 03. @Documented //说明该注解将被包含在javadoc 中 04. public @interface FieldMeta { 05. 06. /** 07. * 是否为序列号 08. * @return 09. */ 10. boolean id() default false ; 11. /** 12. * 字段名称 13. * @return 14. */ 15. String name() default ""; 16. /** 17. * 是否可编辑 18. * @return 19. */ 20. boolean editable() default true ; 21. /** 22. * 是否在列表中显⽰ 23. * @return 24. */ 25. boolean summary() default true ; 26. /** 27. * 字段描述 28. * @return 29. */ 30. String description() default ""; 31. /** 32. * 排序字段 33. * @return 34. */ 35. int order() default 0; 36. }
[java]
获取到注解的帮助类:01. public class Anno { 02. 03. @FieldMeta (id=true ,name="序列号",order=1) 04. private int id; 05. @FieldMeta (name="姓名",order=3) 06. private String name; 07. @FieldMeta (name="年龄",order=2) 08. private int age; 09. 10. @FieldMeta (d
escription="描述",order=4) 11. public String desc(){ 12. return "java 反射获取annotation 的测试"; 13. } 14. 15. public int getId() { 16. return id; 17. } 18. public void setId(int id) { 19. this .id = id; 20. } 21. public String getName() { 22. return name; 23. } 24. public void setName(String name) { 25. this .name = name; 26. } 27. public int getAge() { 28. return age; 29. } 30. public void setAge(int age) { 31. this .age = age; 32. } 33. 34. }
[java]
01. public class SortableField { 02. 03. public SortableField(){} 04. 05. public SortableField(FieldMeta meta, Field field) { 06. super (); 07. this .meta = meta; 08. this .field = field; 09. this .Name(); 10. this .Type(); 11. } 12. 13. 14. public SortableField(FieldMeta meta, String name, Class<?> type) { 15. super (); 16. this .meta = meta; 17. this .name = name; 18. this .type = type; 19. } 20. 21. 22. private FieldMeta meta; 23. private Field field; 24. private String name; 25. private Class<?> type; 26. 27. public FieldMeta getMeta() { 28. return meta; 29. } 30. public void setMeta(FieldMeta meta) { 31. this .meta = meta; 32. } 33. public Field getField() { 34. return field; 35. } 36. public void setField(Field field) { 37. this .field =
field;
运⾏时获取注解,⾸先创建⼀个基类:38. } 39. public String getName() { 40. return name; 41. } 42. public void setName(String name) { 43. this .name = name; 44. } 45. 46. public Class<?> getType() { 47. return type; 48. } 49. 50. public void setType(Class<?> type) { 51. this .type = type; 52. } 53. 54. 55. } [java]
01. public class Parent<T> { 02. 03. private Class<T> entity; 04. 05. public Parent() { 06. init(); 07. } 08. 09. @SuppressWarnings ("unchecked") 10. public List<SortableField> init(){ 11. List<SortableField> list = new ArrayList<SortableField>(); 12. /**getClass().getGenericSuperclass()返回表⽰此 Class 所表⽰的实体(类、接⼝、基本类型或 void ) 13. * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType 。。 14. * getActualTypeArguments()返回表⽰此类型实际类型参数的 Type 对象的数组。 15. * [0]就是这个数组中第⼀个了。。 16. * 简⽽⾔之就是获得超类的泛型参数的实际类型。。*/ 17. entity = (Class<T>)((ParameterizedType)this .getClass().getGenericSuperclass()) 18. .getActualTypeArguments()[0]; 19. // FieldMeta filed = Annotation(FieldMeta.class); 20. 21. if (this .entity!=null ){ 22. 23. /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段 24. * Fields();只返回对象所
表⽰的类或接⼝的所有可访问公共字段 25. * 在class 中getDeclared**()⽅法返回的都是所有访问权限的字段、⽅法等; 26. * 可看API 27. * */ 28. Field[] fields = DeclaredFields(); 29. // 30. for (Field f : fields){ 31. //获取字段中包含fieldMeta 的注解 32. FieldMeta meta = f.getAnnotation(FieldMeta.class ); 33. if (meta!=null ){ 34. SortableField sf = new SortableField(meta, f); 35. list.add(sf); 36. } 37. } 38. 39. //返回对象所表⽰的类或接⼝的所有可访问公共⽅法 40. Method[] methods = Methods(); 41. 42. for (Method m:methods){ 43. FieldMeta meta = m.getAnnotation(FieldMeta.class ); 44. if (meta!=null ){ 45. SortableField sf = new SortableField(Name(),m.getReturnType()); 46. list.add(sf); 47. } 48. } 49. //这种⽅法是新建FieldSortCom 类实现Comparator 接⼝,来重写compare ⽅法实现排序 50. // Collections.sort(list, new FieldSortCom()); 51. Collections.sort(list, new Comparator<SortableField>() { 52. @Override 53. public int compare(SortableField s1,SortableField s2) {
创建⼦类继承基类:
测试类:
转:
1、Annotation 的⼯作原理:
java定义一维数组并赋值JDK5.0中提供了注解的功能,允许开发者定义和使⽤⾃⼰的注解类型。该功能由⼀个定义注解类型的语法和描述⼀个注解声明的语法,读取注解的API ,⼀个使⽤注解修饰的class ⽂件和⼀个注解处理⼯具组成。
Annotation 并不直接影响代码的语义,但是他可以被看做是程序的⼯具或者类库。它会反过来对正在运⾏的程序语义有所影响。
Annotation 可以冲源⽂件、class ⽂件或者在运⾏时通过反射机制多种⽅式被读取。
2、@Override 注解:
java.lang
注释类型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface <em><strong>Override</strong></em>
表⽰⼀个⽅法声明打算重写超类中的另⼀个⽅法声明。如果⽅法利⽤此注释类型进⾏注解但没有重写超类⽅法,则编译器会⽣成⼀条错误消息。
@Override 注解表⽰⼦类要重写⽗类的对应⽅法。
Override 是⼀个Marker annotation ,⽤于标识的Annotation ,Annotation 名称本⾝表⽰了要给⼯具程序的信息。
下⾯是⼀个使⽤@Override 注解的例⼦:54. return s1.getMeta().order()-s2.getMeta().order(); 55. // Name()Name());//也可以⽤compare 来⽐较 56. } 57. 58. }); 59. } 60. return list; 61. 62. } 63. }
[java]
01. public class Child extends Parent<Anno>{ 02. 03. } [java]
01. public class TestAnnotation { 02. 03. @SuppressWarnings ({ "unchecked", "rawtypes" }) 04. public static void main(String[] args) { 05. Parent c = new Child(); 06. List<SortableField> list = c.init();//获取泛型中类⾥⾯的注解 07. //输出结果 08. for (SortableField l : list){ 09. System.out.println("字段名称:"+l.getName()+"\t 字段类型:"+l.getType()+ 10. "\t 注解名称:"+l.getMeta().name()+"\t 注解描述:"+l.getMeta().description()); 11. } 12. } 13. }
<span class="bh_code_a_Java_keywords">class</span> A {
<span class="bh_code_a_Java_keywords">private</span> String id;
A(String id){
<span class="bh_code_a_Java_keywords">this</span>.id = id;
}
<span class="bh_code_a_Java_annotation">@Override</span>
<span class="bh_code_a_Java_keywords">public</span> String toString() {
<span class="bh_code_a_Java_keywords">return</span> id;
}
}
3、@Deprecated注解:
java.lang
注释类型 Deprecated
@Documented
@Retention(value=RUNTIME)
public @interface <em><strong>Deprecated</strong></em>
⽤ @Deprecated 注释的程序元素,不⿎励程序员使⽤这样的元素,通常是因为它很危险或存在更好的选择。在使⽤不被赞成的程序元素或在不被赞成的代码中执⾏重写时,编译器会发出警告。
@Deprecated注解表⽰⽅法是不被建议使⽤的。
Deprecated是⼀个Marker annotation。
下⾯是⼀个使⽤@Deprecated注解的例⼦:
<span class="bh_code_a_Java_keywords">class</span> A {
<span class="bh_code_a_Java_keywords">private</span> String id;
A(String id){
<span class="bh_code_a_Java_keywords">this</span>.id = id;
}
<span class="bh_code_a_Java_annotation">@Deprecated</span>
<span class="bh_code_a_Java_keywords">public</span> <span class="bh_code_a_Java_keywords">void</span> execute(){
System.out.println(id);
}
<span class="bh_code_a_Java_keywords">public</span> <span class="bh_code_a_Java_keywords">static</span> <span
class="bh_code_a_Java_keywords">void</span> main(String[] args) {
A a = <span class="bh_code_a_Java_keywords">new</span> A(<span class="bh_code_a_Java_string">"a123"</span>);
}
}
4、@SuppressWarnings注解:
java.lang
注释类型 SuppressWarnings
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)
public @interface <em><strong>SuppressWarnings</strong></em>
指⽰应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显⽰指定的编译器警告。注意,在给定元素中取消显⽰的警告集是所有包含元素中取消显⽰的警告的超集。例如,如果注释⼀个类来取消显⽰某个警告,同时注释⼀个⽅法来取消显⽰另⼀个警告,那么将在此⽅法中同时取消显⽰这两个警告。
根据风格不同,程序员应该始终在最⾥层的嵌套元素上使⽤此注释,在那⾥使⽤才有效。如果要在特定的⽅法中取消显⽰某个警告,则应该注释该⽅法⽽不是注释它的类。
@SuppressWarnings注解表⽰抑制警告。
下⾯是⼀个使⽤@SuppressWarnings注解的例⼦:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论