注解与反射(二十六)
注解与反射
注解
注解是什么?
注解是种特殊的注释,如果说注释是给人看的话,那么注解就是给程序看的。
Java的注解可以分为三类
- 第一类是由编译器使用的注解,如
@Override
和@SuppressWarning
,这类注解不会被编译进.class文件中,它们在编译后就被编译器抛弃 - 第二类是由工具处理.class文件使用的注解,比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。
- 第三类是程序在运行期间可以读取到的注解,它们在加载后会存在JVM中。
自定义注解
自定义注解使用@interface
来定义,这里有四个常用的参数
- @Target定义注解可以使用在什么上面
- @Retention定义注解在什么时候运行
- @Inherited定义注解是否可继承
- @Documented定义子类是否可以继承父类的注解
package com.reflect.anno;
import java.lang.annotation.*;
public class YuanZhuJie {
@MyAnnotation
public void run(){}
@MyAnnotation2(name = "MyAnno")
public void run2(){}
}
//target设置注解能使用在什么上
@Target(value = ElementType.METHOD)
//retention设置注解运用的范围,runtime > class > source
@Retention(value = RetentionPolicy.RUNTIME)
//document设置注解是否生成进doc文档
@Documented
//inherited设置子类是否可以继承父类的注解
@Inherited
@interface MyAnnotation {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
String name();
int id() default -1; // default可以设置注解参数的默认值
}
反射
什么是反射?反射Reflection就是反方向访问。我们正常的使用方式是引用类,生成类的实例,然后再使用类的属性和方法,这都是在程序运行前都定义好的;而反射就是在程序运行期间,获取到类的属性、方法等再使用。
package com.reflect;
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取Class对象
Class c1 = Class.forName("com.reflect.User");
System.out.println(c1);
//一个类在内存中只有一个Class对象
//一个类被加载后,类的整个结构都会封装在Class对象中
Class c2 = Class.forName("com.reflect.User");
Class c3 = Class.forName("com.reflect.User");
Class c4 = Class.forName("com.reflect.User");
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
}
}
class User {
private String name;
private int age;
private int id;
public User() {
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
在这里我们使用Class.forName来获取到类的信息。