java安全学习之注解
2021.03.30
le31ei
WebSec
 热度
℃
0x01 什么是注解 注解是在java中类、方法、参数前面的一种特殊的注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.itranswarp.learnjava;import javax.annotation.PostConstruct;public class Demo1 { int n; @PostConstruct public void Demo1 () { System.out.println("after construct" ); } public Demo1 () { System.out.println("construct" ); } @Override public String toString () { return "this is demo1" ; } public static void main (String[] args) { Demo1 d = new Demo1(); } }
注解共分为三类:
编译器使用的注释,如@Override
,检查该方法是否正确的实现了覆写
由工具处理.class
文件中使用的注解,一般在底层库使用
程序运行中能够读取的注解,类似于自定义的注解,加载后存在于jvm中
0x02 定义注解 在java中使用@interface
语法来定义注解,例如Override
的定义:
1 2 3 4 @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override {}
Override注解不带任何配置参数。@Target
和Retention
表示的是元注解,能够修饰自定义注解的注解
元注解 @Target
表示定义的注解能够被用到哪些位置:
类或者接口:ElementType.TYPE
字段:ElementType.FIELD
方法:ElementType.METHOD
构造方法:ElementType.CONSTRUCTOR
方法参数:ElementType.PARAMETER
可以定义一个注解同时用于方法或者字段上面,如下所示:
1 2 3 @Target({ElementType.FIELD, ElementType.METHOD}) public @interface Demo2 {}
@Retention
定义了注解的生命周期:
仅编译器:RetentionPolicy.SOURCE
仅class文件:RetentionPolicy.CLASS
运行期:RetentionPolicy.RUNTIME
如果@Retention
不存在,则默认为CLASS
,故在自定义注解时,需要写明@Retention(RetentionPolicy.RUNTIME)
。
还有一些其他属性,可查阅相关文档,不再赘述。
注解参数
在定义注解的时候可以定义一些参数,并且能够赋予默认的值,具体如下,原理类似于接口的定义,定义无方法体的方法。
1 2 3 4 5 6 7 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Report { int type () default 0 ; String level () default "info" ; String value () default "" ; }
0x03 处理注解 注解对java代码的运行逻辑没有任何影响,我们编写的RUNTIME
类型的注解才会在代码运行时产生影响。
所有的注解都继承于java.lang.annotation.Annotation
,读取注解需要使用反射API。
判断是否存在注解的API:
1 2 3 4 Class.isAnnotationPresent(Class) Field.isAnnotationPresent(Class) Method.isAnnotationPresent(Class) Constructor.isAnnotationPresent(Class)
例如,创建构造函数的注解
注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.itranswarp.learnjava;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.CONSTRUCTOR) @Retention(RetentionPolicy.RUNTIME) public @interface Construct_Annotation { String descp () default "no description" ; }
注解使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Demo4 { @Construct_Annotation public Demo4 () { System.out.println("构造函数" ); } @MethodAnnotation public void hello () { System.out.println("hello method" ); } public static void main (String[] args) { Demo4 demo4 = new Demo4(); Constructor[] constructors = demo4.getClass().getConstructors(); for (Constructor con: constructors){ if (con.isAnnotationPresent(Construct_Annotation.class)){ System.out.println("构造函数注解找到" ); } } } }
注解的验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 static void check (Person person) throws IllegalArgumentException, ReflectiveOperationException { for (Field field : person.getClass().getFields()) { Range range = field.getAnnotation(Range.class); if (range != null ) { Object value = field.get(person); if (value instanceof String){ int value_length = ((String) value).length(); System.out.println("当前filed:" + field.getName()+ "的长度是" + ((String) value).length()); if (value_length < range.min() || value_length > range.max()){ throw new IllegalArgumentException("Invalid field: " + field.getName()); } } if (value instanceof Integer){ if ((int ) value < range.min() || (int ) value > range.min()){ throw new IllegalArgumentException("Invalid field: " + field.getName()); } } } } }
注解定义:
1 2 3 4 5 6 7 8 9 10 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Range { int min () default 0 ; int max () default 255 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Person { @Range(min = 1, max = 20) public String name; @Range(max = 10) public String city; @Range(min = 1, max = 100) public int age; public Person (String name, String city, int age) { this .name = name; this .city = city; this .age = age; } @Override public String toString () { return String.format("{Person: name=%s, city=%s, age=%d}" , name, city, age); } }
参考文档
https://www.liaoxuefeng.com/wiki/1252599548343744/1255945389098144
https://blog.csdn.net/pan_junbiao/article/details/85249614