Java注解与反射
3.21学习日记
1.注解
1.1注解是什么?作用?
Annotation–JDK5.0后引入的技术
作用
对程序做出解释并加以规范
格式
@注释名
如:@Override
@SuppressWarnings
例如:
@Override //重写继承方法,覆盖掉,只能修饰方法
public String ToString(){
······
}
@Deprecated //旧方法,不再使用
@SuppressWarning //压住警告,不提示警告,不推荐使用
可以定义范围:value={"all","unchecked","deprecation"}
1.2元注解
-
作用:负责注解其他注解,给其他注解制定规则。
-
类型:
@Target //适用范围
@Retention //表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE<CLASS<RUNTIME),在什么地方有效
@Document //说明该注解将被包含在Javadoc中
@Inherited //说明子类可继承父类的注解
1.3自定义注解
@interface 声明一个注解,格式:public @interface 注解名{定义内容}
//自定义一个注解
@Retention(value=RetentionPolicy.RUNTIME) //在什么地方有效,SOURCE<CLASS<RUNTIME
@Documented //注解是否生成在Javadoc中
@Inherited //子类可继承父类注解
@Target(value=ElementType.METHOD) //给出使用范围,有TYPE,FIFLD,METHOD,PQRAMTER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION,PACKAGE等等
public @interface myAnnoation{
//注解的参数 :参数类型+参数名,若无默认,使用注解时需要带注解中的参数。
int sge() default "";
String value() default "";
String []university() default {"江苏大学,清华大学"};
}//@interface 用来声明一个注解
2.反射机制(Java.Reflection)
2.1作用
Java中的动态语言,可在运行时改变其语言结构,让编程更加灵活。
将反射机制比作一个镜子,可在程序运行时看到其内部结构并进行操作,包括子类的父类,变量,定义的方法等等
2.2原理
JVM加载完类以后,在堆内存中方法区中产生一个Class类型对象(一个类一个Class对象),这个对象便可动态地观察内部结构并加以改变。
反射机制是由下向上,程序运行是从上至下,故称反射。
2.3使用
- 反射可得到的信息:类属性,方法,构造器,变量,接口等
//Class常用方法:
//Declare-->获取全部,不加仅获取public
static ClassforName(String name);//返回类名name的class对象
Object newInstance(); //调用缺省(无参)构造函数,返回Class的一个实例
getName(); //返回此Class对象所代表的实体(接口,类,数组,或void)名称
Class getSuperClass();//返回当前Class对象的父类的Class对象
Class[] getintreface();//返回当前Class对象接口
ClassLoderd getClassLoder();//返回类的类加载器
Constructor[]getConstructors();//返回一个包含某些Constructor对象的数组,构造器
Constructor[]getConstructors(类型.class,···);//指定构造器
Constructor[]getDeclareConstructors();
Method getMothed(String name/*指定方法名*/···,parameterTypes:null|参数.class/*方法所带参数*/);//返回一个Method对象,此对象的参数类型为paraType,获取本类及父类所有public方法,同理,DeclareMothed获取本类所有方法。
Field [] getDeclareFields();//返回Field对象的一个数组 Field-->属性 适用于全部权限
Field [] getFields();//仅适用于public
- 获取Class对象的方法
- Class c1=对象名.getClass(); //通过对象名获得
- Class c2=Class.forname(“类地址”); //通过forname
- Class c3=类名.Class; //通过类名
- Class c4=Integer.Type //少用
-
哪些类型有Class对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3f4YuUKA-1679383105390)(D:\Users\s\Pictures\Snipaste_2023-03-20_20-46-30.png)]
Class c1=Object.class;//类
Class c2=Comparable.class;//接口
Class c3=String[].class;//String数组
Class c4=int[].class;//一维数组
Class c5=int[][].class;//二维数组
Class c6=Override.class;//注解
Class c7=ElementType.class;//枚举类型
Class c8=void.class;//返回值
Class c9=Class.class;//Class
Class c10=Integer.class;//基本数据类型
注意:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQafloMH-1679383105391)(D:\Users\s\Pictures\Snipaste_2023-03-20_20-50-50.png)]
//举例
//获得类
Class c1=ClassForName("lang.java.reflection.tryone")
//对对象进行操作
c1.getname();
c1,getsimplename();
//获得类属性
c1.getfields();
-
有了Class对象,可以干什么?
- 创建对象:调用Class对象的newInstance()方法
-
该类必须有无参构造器
-
该类的构造器的访问权限足够
//通过对象获得Class Class class=person1.getClass(); //调用Class的newInstance方法 Person p1=(Person)class.newInstance();//需强转,默认为object对象 ,调用的无参构造器
- 无无参构造器时,通过有参构造器创建对象
//获取Class Class c2=ClassForName("lang.java.reflection.tryone"); //调用有参构造器 Construct construct=c2.getConstructor(~.class,~.class,~.class); //通过有参构造器创建对象 Person person2=(Person)construct.newInstance("","",""); //通过反射调用创建对象的方法 //1.获取方法 //2.对某对象使用该方法 Method setname=c2.getDeclareMothed("方法名",方法所带参数类型.class);//获取方法 setName.invoke(person/*对象*/,"参数");//调用方法 System.out.println(person.getName();)//测试 //通过反射操作属性 Field name=class.getDelcareField("name"); name.setName(对象,"南楠木兮"); //关闭程序检测可以让反射操作私有private name.setAccessible(true);//默认打开,所以true为关。
- 性能:普通>关闭程序检测的反射>默认反射