学习:菜鸟教程
注解(Annotation)
内置的注解
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
- @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
元注解
**作用在其他注解的注解 **
- @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
- @Documented - 标记这些注解是否包含在用户文档中。
- @Target - 标记这个注解应该是哪种 Java 成员。
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
自定义注解(@interface)
使用 @interface 自定义注解时﹐自动继承了java.lang.annotation.Annotation接口
- interface用来声明一个注解﹐格式:public @interface注解名{定义内容}
- 其中的每一个方法实际上是声明了一个配置参数.
- 方法的名称就是参数的名称.
- 返回值类型就是参数的类型(返回值只能是基本类型,Class , String , enum )
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般参数名为value
- 注解元素必须要有值﹐我们定义注解元素时,经常使用空字符串,0作为默认值.
展示:
1 2 3 4 5 6 7 8 9 10
| @Documented @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface MyAnno1{ String name() default "瞳瞳"; int id() default -1; String[] schools() default {"B站大学","哈哈大学"}; }
|
反射
获取Class的三方式
| 方式 |
备注 |
| Class.forName(“完整类名带包名”) |
静态方法 |
| 对象.getClass() |
|
| 任何类型.class |
|
通过反射实例化对象
newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。
c1.newInstance();
Class类方法
| 方法名 |
备注 |
| T newInstance() |
创建对象 |
| String getName() |
返回完整类名带包名 |
| String getSimpleName() |
返回类名 |
| Field[] getDeclaredFields() |
返回类中所有的属性 |
| Field getDeclaredField(String name) |
根据属性名name获取指定的属性 |
Field类方法
| void set(Object obj, Object value) |
设置属性值 |
| Object get(Object obj) |
读取属性值 |
set()不可以直接访问私有属性,需要打破封装,才可以
1
| field1.setAccessible(true);
|
1 2 3 4 5 6 7 8
| Class c1 = Class.forName("reflection.Person"); Object obj = c1.newInstance(); System.out.println(obj);
Field f1 = c1.getDeclaredField("name"); f1.setAccessible(true); f1.set(obj,"xm"); System.out.println(obj);
|
注解与反射
获取类注解实例
获取属性注解实例
1 2 3 4
| Field f1 = c1.getDeclaredField("name");
Annotation[] a2 = f1.getAnnotations();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Person person=new Person(); Class c1 = person.getClass();
Annotation a1 = c1.getAnnotation(AnnoTable.class); System.out.println(a1);
Field f1 = c1.getDeclaredField("name");
Annotation[] a2 = f1.getAnnotations(); for (Annotation annotation : a2) { System.out.println(annotation); }
Method m1 = c1.getDeclaredMethod("setSex", String.class);
for (Annotation annotation : m1.getAnnotations()) { System.out.println(annotation); }
|
利用注解与反射自定义一个Frame
注解
1 2 3 4 5 6
| @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyTest { String value() default ""; }
|
测试
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class A_R {
@MyTest public void test1() { System.out.println("-----------test1----------------"); }
public void test2() { System.out.println("-----------test2----------------"); }
@MyTest public void test3() { System.out.println("-----------test3----------------"); }
@MyTest(value = "hello") public void test4() throws Exception { System.out.println("-----------test4----------------"); Class a = A_R.class; Method m = a.getDeclaredMethod("test4"); MyTest t1 = m.getAnnotation(MyTest.class); System.out.println(t1.value());
} public static void main(String[] args) throws Exception{ A_R a=new A_R(); Class c=A_R.class; Method[] m = c.getDeclaredMethods(); for (Method method : m) { if (method.isAnnotationPresent(MyTest.class)){ method.invoke(a); } } } }
|