当前位置: 首页 > news >正文

注解与反射

注解

注解(Annotation) 可以被其他程序(如:编译器)读取

​ 可通过反射机制编程实现对这些元数据的访问

注解都定义在 java.lang.* 下

@Verride  //重写的注解
@Deprecated  // 已过时的,表示不鼓励程序员使用这样的元素(很危险或有更好的选择)
@SuppressWarnings // 镇压警告@SuppressWarnings("all")  // 镇压所有的警告

元注解

元注解作用是负责注解其他注解

@Target  // 用于描述注解的使用范围(被描述的注解可用于什么地方)
@Retention //表示需要在什么级别保存该注释信息(SOURCE < CLASS < RUNTIME)
@Document // 说明该注释将被包含在javadoc 中
@Inherited // 说明子类可以继承父类中的该注解

反射(Reflection)

反射:加载类,允许以编程的方式拿出类中各种成分(成员变量、方法、构造器等)

1、 反射第一步:加载类,获取类的字节码:Class 对象
2、 获取类的构造器 : Constructor 对象
3、 获取类的成员变量:Field 对象
4、 获取类的成员方法:Method 对象获取Class 对象的三种方法Class c1 = 类名.class调用Class 提供的方法 : public static Class forName(String package);Object提供的方法: public Class getClass(); 	Class c3 = 对象.getClass();

获取反射的字节码文件

Class c1 = 类名.class
c1.getName();								// 返回此字节码类的全类名
c1.getSimpleName();							// 返回字节码类的简名字:类名Class c2 = Class.forName("com.whoami.Test");  
System.out.print(c1 == c2);				// 两种方法拿到的为同一个class 文件Test t = new Test();
Class c3 = t.getClass();
System.out.print(c3 == c2);				//三种方法拿到的为同一个class 文件

获取反射的类中构造器

作用:依然是初始化对象返回

Class c = Test.class			// 获取类的字节码文件
Constructor[] constructors = c.getConstructors();  // 通过字节码文件获取到类的所有构造器(只能获取public修饰的构造器)c.getDeclaredConstructors();	// 获取类中所有的构造器c.getConstructor();		// 获取单个构造器(只有public 修饰)c.getDeclaredConstructor(); // 获取单个构造器c.getConstructor(String.class,int.class); // 匹配有参构造器
for(Constructor construcotr : constructors){constructor.getName				// 获取构造器名字constructor.getParameterCount();	// 获取构造器参数
}

constructor1.newInstance();					// 调用构造器对象表示的构造器,并传入参数,完成初始化
constuctor1.setAccessible(true);			// 禁止检查访问权限,即此反射构造器可调用私有属性

获取类的成员变量

作用:依然是赋值、取值

1、 反射第一步:必须是先得到类的Class 对象Class c = Cat.class;
2、 获取类的全部成员变量Field[] fields = c.getDeclaredFields();				// 获取类的全部成员变量c.getFields();					// 获取类的全部成员变量(只获取public 的)Field  fName = c.getField("变量名");						// 获取某个成员变量(只能获取public 的)	c.getDeclaredField("变量名");				// 获取某个成员变量for (Field field : fields){field.getName()	;			// 获取变量名firld.getType();			// 获取变量类型}

1、取值、赋值Class c  = Test01.class;Test01 test01 = new Test01();Field fName = c.getDeclaredField("name")
//赋值Test01 test01 = new Test01();fName.setAccessible(true);		// 禁止访问控制权限,暴力反射fName.set(test01,"咖啡猫");		// 赋予test对象(即Test01类)成员变量值//取值String name = (String) fNmae.get(test01);	// 取出类中的fName的变量名的属性值

获取类的成员方法

作用:依然是执行

Class c = Test01.class;
Method[] methods = c.getDeclaredMethods();			// 获取类的全部成员方法c.getMethods();					// 获取类的全部成员方法(只有public 修饰)c.getMethod("run",param);			// 获取某个成员方法(run方法+参数匹配) (只有public 修饰)c.getDeclareMethod("run",param);		//  获取某个成员方法(run方法+参数匹配)

Class c = Test01.class; 		
Test01 test01 = new Test01();
run.setAccessible(true);				// 暴力强转
Object result = run.invoke(test01,param);								// 触发某个对象中的方法执行(返回值为Object,返回值可指定)

反射的作用

基本作用 :可以得到一个类的全部成分然后操作

可以破坏封装性

最重要的用途:适合做Java 的框架,基本上,主流的框架都会基于反射设计出一些通用的功能


注解

让其他程序根据注解信息来决定怎么执行该程序

自定义注解

public @interface 注解名称{public 属性类型 属性名() default 默认值;
}// 例
public @interface MyTest1{String aaa();boolean bbb() default true;Stringp[] ccc();
}特殊属性名:value如果注解中只有一个value 属性,使用注解时,value名称可以不写

注解的本质是一个接口,Java中的所有注解都是继承了Annotation 接口

@注解(...): 其本质就是一个实现类对象


元注解

修饰注解的注解

@Target     			// 作用:声明被修饰的注解只能在哪些位置使用@Target(ElementType.TYPE)1. TYPE, 类,接口2. FIELD, 成员变量3. METHOD, 成员方法4. PARAMETER, 方法参数5. CONSTRUCTOR, 构造器6. LOCAL_VARLABLE,局部变量@Retention 				// 作用:声明注解的保留周期@Retention(RetentionPolicy.RUNTIME)1.SOUCE				// 只作用于源码阶段,字节码文件中不存在2.CLASS	(默认值)			// 保留到字节码文件阶段,运行阶段不存在3.RUNTIM(开发常用)			// 一直保留到运行阶段

注解的解析

判断类上、方法上、成员变量上是否存在注解,并把注解里的内容解析出来

指导思想:要解析谁上面的注解,就应该先拿到谁

Class c = Demo.class;					// 声明取出class 类的反射字节
Method m = c.getDeclaredMethod("test1") 	// 从反射的class 对象中获得成员方法
if(m.isAnnotationPresent(MyTest.class)){	// isAnnotationPresent(),判断此类/方法/变量是否存在指定的注解,返回boolenMyTest4 mytest4 = (MyTest4) m.getDeclaredAnnotation(MyTest.class);	// 指定注解并取出,返回值为Annotation 类m.getDeclareAnnotations()		// 获取当前对象上面的注解mytest4.value();mytest4.aaa();mytest4.bbb();
}

注解的应用场景
package zhujie;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;public class AnnotationTest3 {@MYTestpublic void test1(){System.out.println("test1");}@MYTestpublic void test2(){System.out.println("test2");}@MYTestpublic void test3(){System.out.println("test3");}@MYTestpublic void test4(){System.out.println("test4");}public static void main(String[] args) throws Exception{AnnotationTest3 annotation = new AnnotationTest3();         // new 对象,用于invoke 执行方法时使用到Class c = AnnotationTest3.class;                    // 利用反射定义class 对象为当前类Method[] methods=c.getDeclaredMethods();            // 利用当前类的class 对象取出所有的方法for (Method method : methods) {                     // 对于所有的方法进行循环if(method.isAnnotationPresent(MYTest.class)){   // 对于循环的每一个反射的方法进行判断,判断是否存在MYTest 注解method.invoke(annotation);                  // 若存在则进行invoke 执行该函数}}}}
http://www.hskmm.com/?act=detail&tid=38696

相关文章:

  • 2025 铝型材源头厂家最新推荐排行榜:优选企业深度解析,佛山亿生 / 永利坚及新锐品牌选购指南
  • 2025年工业生产发酵罐源头厂家权威推荐榜单:实验室发酵罐/醋酸发酵罐/工厂发酵罐源头厂家精选
  • 2025 年最新充电桩厂家口碑推荐排行榜:技术创新与服务保障双优品牌权威测评电动自行车充电桩/电动汽车充电桩公司推荐
  • Java-SE DAY3
  • 深入解析:C语言内存布局:虚拟地址空间详解
  • 奶奶都能看懂的 C++ —— vector 与迭代器
  • AI|AI优化公司智能GEO优化解决方案
  • Java-SE Day2
  • 2025 年无缝管厂家最新推荐榜,聚焦企业技术实力与市场口碑深度解析
  • 2025 年最新波形护栏厂家推荐排行榜:结合协会测评数据,精选行业优质品牌路侧波/乡村公路/县级公路波形护栏板公司推荐
  • 测试人请查收:金融级系统“三高”挑战下的AI测试工具栈与技术内幕
  • 年度 Demo Day!见证语音 AI 年度场景诞生!丨Convo AIRTE2025
  • 科学数据规模化迁移:Benchling从EAV模型转向JSONB的性能优化实践
  • 2025年10月杭州丝绸购买榜:万事利湖滨步行街店权威排行
  • 2025年10月加拿大海参产品推荐榜:谷得斯特领衔五强对比
  • 2025年10月宠物空气净化器产品推荐:性价比排行与选购攻略
  • Docker 部署 Debian 全流程教程
  • 2025年10月深圳离婚律师推荐榜:五强对比与选择指南
  • 2025 年花岗岩厂家最新推荐榜:覆盖路沿石、火烧板等全品类,结合行业协会测评数据精选优质厂家
  • 2025年10月房产继承律师推荐榜:五强对比与选择指南
  • 2025 年控制柜生产厂家最新推荐排行榜:聚焦换热机组 / 污水处理等领域品牌技术实力与服务能力测评
  • VS-和-CrystalReport-报告指南-全-
  • WebSocket-基础知识-全-
  • Paper: Accelerating Vision Transformers with Adaptive Patch Sizes
  • 字符串专题
  • 2025年包装机厂家权威推荐榜:自动包装机、半自动包装机源头企业综合测评与选购指南
  • 2025年清洗剂厂家权威推荐榜:水基型清洗剂专业解析,高效环保与行业应用深度评测
  • 古代的时辰,几更天与现在的时间对应关系是什么?
  • 2025年实用金属铝合金打包机厂家推荐榜单:多场景适配的优质之选
  • Unity-物理学习指南-全-