Java中的注解和反射实例详解
一、注解
注解(Annotation):从jdk5.0开始引进,可以对程序进行解释或被其他程序读取。
注解格式:"@注释名",并可以添加一些参数。
例:@MyAnnotation(value=‘value')
1、内置注解
@override:用于修饰方法,表示该方法声明是重写或实现一个父类的方法
@Deprecated:用于修饰方法、属性、类,表示已过时不建议使用的
@SuppressWarnings:用于抑制编译时的警告信息
2、元注解
作用:用于注解其他注解
@Target:用于描述注解的适用范围
例:@Target(ElementType.ANNOTATION_TYPE)适用范围为注解定义
@retention:表示需要在什么级别保存该注解信息
SOURCE-源码级别
CLASS-class级别
RUNTIME-运行级别
SOURCE 例:@Retention(RetentionPolicy.RUNTIME)此注解运行时有效 @Documented:表示是否将注解生成在Javadoc中 @Inherited:表示子类可以继承父类的注解 3、自定义注解 注解定义:@interface+注解名 测试: 反射(Reflection)是java被视为动态语言的关键,反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。 优缺点:具有灵活性但是效率较低。 Classc=Class.forName(java.lang.String) 1、Class类 某个类的属性、方法和构造器、某个类实现了哪些接口,JRE都为其保留了一个不变的Class类型的对象,同一个类的所有对象共享同一个Class对象。 Class类具有以下特点: Class类的常用方法: 2、通过反射获取Class对象: 所有的类都可以通过反射获取其Class对象。 下面通过例子列举获取类的Class对象的三种方式: 输出结果:
@Target(ElementType.METHOD)//作用在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interfaceMyannotation1{
//注解的参数:参数类型+参数名();
StringParameter1();
intParameter2()default-1;//默认值为-1代表不存在
}
@Target(ElementType.METHOD)//作用在方法上
@Retention(RetentionPolicy.SOURCE)//源码中有效
@interfaceMyannotation2{
StringValue();//只有一个参数时,参数名用Value
}
//有默认值的参数可以不填没有默认值的参数必填,并且参数填写没有顺序
@Myannotation1(Parameter1="Parameter1")
//参数定义为Value时,前面的"Value="可以省略
@Myannotation2("Value")
publicvoidtest01(){
}
二、反射
方法名
功能说明
staticClass.forName(Stringname)
返回指定类名name的Class对象
ObjectnewInstance()
调用缺省构造函数,返回Class对象的一个实例
getName()
返回此Class对象所表示的实体(类、接口、数组类或void)的名称
ClassgetSuperClass()
返回当前Class对象的父类Class对象
Class[]getinterfaces()
返回当前Class对象的接口
ClassLoadergetClassLoader()
返回该类的类加载器
Constructor[]getConstructors()
返回一个包含某些Constructor对象的数组
MethodgetMethod(Stringname,ClassT)
返回一个Method对象,此对象的形参类型为paramType
Field[]getDeclaredFields
返回Field对象的一个数组
//新建Person类
classPerson{
Stringname;
intage;
intid;
publicPerson(){
}
publicPerson(Stringname,intage){
this.name=name;
this.age=age;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
}
//测试
publicclasstest02{
publicstaticvoidmain(String[]args)throwsClassNotFoundException{
Personperson=newPerson();
//方式一、通过包名获取
Classclass1=Class.forName("com.reflection.Person");
System.out.println(class1.hashCode());
//方式二、通过对象获取
Classclass2=person.getClass();
System.out.println(class3.hashCode());
//方式三、通过类获取
Classclass3=Person.class;
System.out.println(class3.hashCode());
}
}
结论:三种方式获取的Class对象为同一个。
3、获取类的运行时结构
publicclasstest03{ publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchFieldException,NoSuchMethodException{ Classc1=Class.forName("com.reflection.Person"); //获得类的名字 Stringname=c1.getName();//获得包名加类名 StringsimpleName=c1.getSimpleName();//获得类名 //获得类的属性 Field[]fields=c1.getFields();//获得类的所有公有属性 Field[]declaredFields=c1.getDeclaredFields();//获得类的所有属性 Fieldfield=c1.getField(name);//获得类的指定公有属性 FielddeclaredField=c1.getDeclaredField(name);//获得类的指定属性(所有类型均可) //获得类的方法 Method[]method=c1.getMethods();//获得本类及其父类的所有公有方法 Method[]declaredMethods=c1.getDeclaredMethods();//获得本类的所有方法 MethodgetName=c1.getMethod("getName",null);//获取指定方法(本类及其父类的所有公有方法) MethodsetName=c1.getDeclaredMethod("setName",String.class);//获取指定方法(本类的所有方法) //获得类的构造器 Constructor[]constructors=c1.getConstructors();//获取所有公有构造器 Constructor[]declaredConstructors=c1.getDeclaredConstructors();//获取所有构造器 Constructorconstructor=c1.getConstructor(String.class,int.class);//获取指定公有构造器 ConstructordeclaredConstructor=c1.getDeclaredConstructor(String.class,int.class);//获取指定构造器 } }
4、通过反射构造对象
publicclassTest04{ publicstaticvoidmain(String[]args)throwsClassNotFoundException,IllegalAccessException,InstantiationException,NoSuchMethodException,InvocationTargetException,NoSuchFieldException{ //获得Class对象 Classc1=Class.forName("com.reflection.Person"); //通过反射创建对象 Personperson=(Person)c1.newInstance();//本质上是调用了无参构造器 Constructorconstructor=c1.getDeclaredConstructor(String.class,int.class);//获取有参构造器 Personperson2=(Person)constructor.newInstance("name",18);//调用有参构造器创建对象 //通过反射调用普通方法 MethodsetName=c1.getDeclaredMethod("setName",String.class);//获取方法 setName.invoke(person,"name");//通过invoke调用方法 //通过反射操作属性 Fieldname=c1.getDeclaredField("name");//获取name属性 name.setAccessible(true);//关闭安全检测,关闭后可以访问私有属性(true为关闭,false为打开,默认是false) name.set(person,"lalala");//设置属性的值 } }
5、通过反射获取注解的信息
创建类和注解
@Testclass("db_Student2")//类注解 //创建学生类 classStudent2{ @Testfield(columnname="name",type="varchar",length=20)//属性注解 Stringname; @Testfield(columnname="age",type="int",length=3) intage; @Testfield(columnname="ID",type="int",length=10) intID; publicStudent2(){ } publicStudent2(Stringname,intage,intID){ this.name=name; this.age=age; this.ID=ID; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicintgetID(){ returnID; } publicvoidsetID(intID){ this.ID=ID; } } //类的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interfaceTestclass{ Stringvalue(); } //属性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interfaceTestfield{ Stringcolumnname(); Stringtype(); intlength(); }
测试
publicclasstest05{ publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchFieldException{ Classc1=Class.forName("com.zjrcu.reflection.Student2"); //通过反射获得注解 Annotation[]annotations=c1.getAnnotations(); for(Annotationannotation:annotations){ System.out.println(annotation); } //通过反射获得注解value的值 Testclasstestclass=(Testclass)c1.getAnnotation(Testclass.class); Stringvalue=testclass.value(); System.out.println(value); //获取类中指定注解的value值 Fieldf=c1.getDeclaredField("name"); Testfieldtestfield=(Testfield)f.getAnnotation(Testfield.class); System.out.println(testfield.columnname()); System.out.println(testfield.length()); System.out.println(testfield.type()); } }
总结
到此这篇关于Java中的注解和反射的文章就介绍到这了,更多相关Java注解和反射内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。