注解和反射
java注解和反射
注解
注解(Annotation)
- 作用
- 可以对程序作出解释(和注释(comment)相同)
- 可以被其他程序读取(编译器等)
- 格式:@注释名,还可以添加一些参数值
- eg:@SuppressWarnings(value="unchecked")
- 使用范围:package、class、method、field等,可以通过反射机制编程实现对这些元数据的访问
内置注解
- @Override:重写注解
- @Deprecated:不鼓励使用的属性、类(通常是危险的或者有更好的选择)
- @SuppressWarnings:抑制编译时的警告信息(需要添加一个参数才能正常使用)
- @SuppressWarnings("all")
- @SuppressWarnings("unchecked")
- @SuppressWarnings(value={"unchecked","deprecation})
元注解
负责注解其他注解
- java的4个标准元注解(meta-annotation)
- @Target:描述注解的使用范围
- @Retention:表示需要在什么级别保存注解信息,用于描述注解的生命周期(SOURCE(源码时有效)<CLASS(class文件有效)<RUNTIME(运行时有效)(一般定义为RUNTIME))
- @Documented:该直接将被包含到javadoc中(生成文档注释)
- @Inherited:子类可以继承父类中的注解
自定义注解
@interface 注解名{定义内容}
每个方法实际上是声明了一个配置参数
方法的名称就是参数的名称
返回值类型就是参数的类型(返回值只能是基本类型Class、String、enum)
可以通过default来声明参数的默认值,没有默认值使用时必须给注解赋值
如果只有一个参数成员,一般参数名为value
注解元素必须要有值
public class Demo01 { @Annotation(age=18) public void text(){ } } @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface Annotation{ String name() default ""; int age(); }
反射
反射对象
Class类
一个类在内存中只有一个Class对象
一个类被加载后,类的整个结构都会被封装在Class对象中
获得Class对象
Person person = new Person(); //通过对象获得 Class c1 = person.getClass(); //forname获得,需要抛出异常 Class c2 = Class.forName("路径名"); //通过类名获得 Class c3 = Person.class; //基本内置类型的包装类都有一个Type属性 Class c4 = Integer.TYPE;
类的初始化
-
类的主动引用(一定会发生类的初始化)
- main方法
- new一个类
- 静态成员和静态方法
- 使用java.lang.reflect包的方法对类进行反射调用
- 初始化类时父类没有被初始化则先初始化父类
-
类的被动引用(不会发生类的初始化)
- 访问静态域时,只有真正声明这个域的类才会初始化(通过子类引用父类的静态变量不会导致子类初始化)
- 通过数组定义类的引用,不会触发此类的初始化
- 引用常量不会触发此类的初始化
类加载器
public static void main(String[] args) throws ClassNotFoundException { //获得系统类加载器 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //获得系统类加载器的父类加载器(拓展类加载器) ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //获得拓展类加载器的父类加载器(根加载器,无法直接获取) ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //获得指定类是由那个加载器加载的 ClassLoader classLoader = Class.forName("路径").getClassLoader(); System.out.println(classLoader); //获得类加载器可以加载的路径 System.out.println(System.getProperty("java.class.path")); }
类的结构
public static void main(String[] args) throws ClassNotFoundException { Class<?> aClass = Class.forName("路径"); //获得类名 System.out.println(aClass.getName());//类名+包名 System.out.println(aClass.getSimpleName());//类名 //获得类的属性 Field[] fields = aClass.getFields();//只能获得public属性 for (Field field : fields) { System.out.println(field); } Field[] declaredFields = aClass.getDeclaredFields();//能获得所有属性 for (Field declaredField : declaredFields) { System.out.println(declaredField); } //获得类的方法 Method[] methods = aClass.getMethods();//本类及父类所有的public方法 for (Method method : methods) { System.out.println(method); } Method[] declaredMethods = aClass.getDeclaredMethods();//本类的所有方法 for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } //获得构造器 Constructor<?>[] constructors = aClass.getConstructors();//本类及父类所有的public构造器 for (Constructor<?> constructor : constructors) { System.out.println(constructor); } Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();//本类的构造器 for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } }
通过反射来创建对象
public class Demo04 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //获得class对象 Class<?> aClass = Class.forName("com.mixian.opp.Demo03"); //创建对象 Object o = aClass.newInstance(); System.out.println(o); //通过构造器创建对象 Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class); Object mixian = declaredConstructor.newInstance("mixian"); System.out.println(mixian); //通过反射调用方法 Method setName = aClass.getDeclaredMethod("setName", String.class); setName.invoke(o,"mixian");//激活 //通过反射操作属性 Field name = aClass.getDeclaredField("name"); name.setAccessible(true);//私有属性不能直接操作,需要关闭程序的安全监测 name.set(o,"mixian"); } }
通过反射获得注解
public class Demo06 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class<?> aClass = Class.forName("com.mixian.opp.Student"); //通过反射获得注解 AnnotatedType[] annotatedInterfaces = aClass.getAnnotatedInterfaces(); for (AnnotatedType annotatedInterface : annotatedInterfaces) { System.out.println(annotatedInterface); } //获得类value的值 xian annotation = aClass.getAnnotation(xian.class); String value = annotation.value(); System.out.println(value); //获得类指定的注解 Field age = aClass.getDeclaredField("age"); xian annotation1 = age.getAnnotation(xian.class); System.out.println(annotation1.value()); } } @xian("xian") class Student{ @xian("xian") private String name; @xian("xian") private int age; } @Target({ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @interface xian{ String value(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix