注解
可以被其他程序(编译器)读取的解释
@Override 重写
@Deprecated 此部分代码已废弃
@SuppressWarnings("all") 镇压警告
元注解
注释其他注解
@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
@Retention:表示需要在什么级别保存该注释信息﹐用于描述注解的生命周期(SOURCE< CLASS < RUNTIME)
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
自定义注解
@interface 注解名 {定义内容}
- @interface自定义注解时,自动继承了java.lang.annotation.Annotation接口。
- 可以通过default来声明参数的默认值。
- 注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test {
@MyAnnotation(name = "name") //因为有默认值,可以不写部分参数
public void test1(){}
}
@Target({ElementType.TYPE,ElementType.METHOD}) //注解可以在类和方法上使用
@Retention(RetentionPolicy.RUNTIME) //注解可以在运行时执行
@interface MyAnnotation{
//注解的参数
String name(); //default表示注解的参数有默认值。
int id() default -1; //默认值为-1表示不存在。
}
反射
通过反射获取类的Class对象
Class c = Class.forName("路径"); //路径为src下包名.类名,如:com.pojo.User,需要抛出异常
- 一个类在内存中只有一个Class对象
- 一个类被加载后,类的整个结构会被封装在Class对象中
获取类名
c.getName();
c.getSimpleName(); //获取简单类名
获取类的属性
c.getFields(); //只能获取public的属性
c.getDeclaredFields(); //获取类的所有属性
//可以获得指定的属性
c.getField(String fieldName); //获取指定的public的属性
c.getDeclaredField(String fieldName); //获取指定的属性
获得类的方法
c.getMethods(); //获得本类及父类的所有public方法
c.getDeclaredMethods(); //获得本类的所有方法
//可以获得指定的属性
c.getMethod(String methodName,Class<?> parameterTypes); //获得指定的public方法
c.getDeclaredMethod(String methodName,Class<?> parameterTypes); //获得指定的方法
parameterTypes:有参构造的参数类型.class,例如参数为String,则parameterType为String.class
获取构造器
c.getConstructor(Class<?> parameterTypes); //获取有参构造器,需要抛出异常
parameterTypes:有参构造的参数类型.class,例如参数为String,则parameterType为String.class
构造对象
//先获取有参构造器
Constructor constructor = c.getConstructor(int.class);
//再构造对象
constructor.newInstance(1); //单独使用会调用无参构造,需要抛出异常
调用方法
//先构造和获取指定的方法
User user = (User)c.newInstance();
Method setName = c.getDeclaredMethod("setName", String.class);
//再调用方法
setName.invoke(user,""); //激活执行方法
invoke(传递的对象,传递的值)
操作属性
//先获得方法
Field name = c.getDeclaredField("name");
//关掉权限检测,因为不能直接操作私有属性
name.setAccessible(true);
//传入属性
name.set(user,"");
set(传递的对象,传递的值)
关闭权限检测
setAccessible(true); //需要反复调用反射时使用,可以调优性能