java 反射 属性注解_JAVA高级特性反射和注解

反射:

反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相关的语义。

反射操作核心的概念“一切的操作都将使用Object完成, 类、 数组的引用都可以使用Object进行接收”

b5fe2972-6c0b-44aa-ac55-6cd42411aaab.png

实例化类对象的方式。

1。 Class> c1 = Class . for Name( " 完整的类路径")  常用

2。 Class>c2 =类名.class

3。 Class>c3 =new 类名( ).getClass( )

Class 类常用操作

4732a9a3-09fa-40c9-8a9a-0dba6dbf4df4.png

65135be8-c74a-489c-9e91-5a80badb4776.png

1 getSimpleName()获取类名2 getName()获取完整的“包,类”名称;3 Class 类的使用4 无参构造实例化对象5 public static void main(String[] args) throwsClassNotFoundException, InstantiationException,6 IllegalAccessException {7 //通过类路径获取类Class对象

8 Class> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");9 //调用newInstance()方法, 调用无参构造创建类对象

10 Person person =(Person) clazz.newInstance();11 //操作对象

12 person.setAge(12);13 person.setName("张三");14 System.out.println(person);15 }16 有参构造实例化对象17 public static void main(String[] args) throwsClassNotFoundException,18 InstantiationException, IllegalAccessException,19 IllegalArgumentException, InvocationTargetException {20 //获取类的Class对象

21 Class> clazz =clazz.forName("com.project.enmutestdemo.fanshe.Person");22 //通过参数类型获取类的具体的某一个构造器

23 Constructor> c = clazz.getConstructor(String.class,int.class);24 Person person = null;25 //传入实参, 通过构造器创建类对象

26 person = (Person) c.newInstance("张三", 20);27 System.out.println(person);

Constructor 构造器类 常用的方法

d225de11-398f-4fea-b0a6-458a3d59ecf2.png

Field 类常用方法

6f3044b3-96f8-400c-99fa-5f16340d8cad.png

1 getmodified 获取访问修饰符(public private。。。)2 取得类中属性3 public static void main(String[] args) throwsClassNotFoundException {4 Class> clazz = null;5 //通过类路径获取类Class对象

6 clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");7 //取得本类的属性

8 Field[] f =clazz.getDeclaredFields();9 //循环操作类的属性

10 for(int i = 0; i < f.length; i++){11 //取得该属性的类型

12 Class> t =f[i].getType();13 //取得该属性的修饰符数字

14 int mo =f[i].getModifiers();15 //通过修饰符数字取得属性的修饰符

16 String priv =Modifier.toString(mo);17 System.out.print("本类属性: ");18 System.out.print(“ 修饰符为: ”+priv+" ");19 System.out.print(“类型为: ”+t.getName()+" ");20 System.out.print(“名称为: ”+f[i].getName()+”\n”);21

22

23 通过反射 操作属性24 //获取类的Class对象

25 Class> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");26 //调用无参构造器创建类对象

27 Object obj =clazz.newInstance();28 //通过属性名称获取属性的Field对象

29 Field nameFiled = clazz.getDeclaredField("name");30 //通过set方法对对象的属性进行赋值

31 nameFiled.set(obj, "张三");32 //通过get方法获取对象的属性值

33 System.out.println(" 姓名: "+nameFiled.get(obj));34

35 操作类中的属性36 //获取类的Class对象

37 Class> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");38 //调用无参构造器创建类对象

39 Person obj =clazz.newInstance();40 //通过属性名称获取属性的Field对象

41 Field nameFiled = clazz.getDeclaredField("name");42 //设置该属性的访问权限为可访问

43 nameFiled.setAccessible(true);44 //通过set方法对对象的属性进行赋值

45 nameFiled.set(obj, "张三");46 //通过get方法获取对象的属性值

47 System.out.println(" 姓名: "+nameFiled.get(obj));

Method 类常用方法

36af9048-d938-44e3-bb4b-3d8c13859653.png

1 取得类的全部方法2 //获取类的Class对象

3 Class> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");4 Method[] method = clazz.getDeclaredMethods();//获取本类所有方法

5 for(int i = 0; i < method.length;i++){//循环操作方法

6 Class> r = method[i].getReturnType();//获取方法的返回值类型

7 Class> p[] =method[i].getParameterTypes();//获取方法的参数类型

8 int xx = method[i].getModifiers();//获取方法的修饰符数字

9 System.out.print(Modifier.toString(xx)+" ");//获取修饰符

10 System.out.print(r.getSimpleName()+" ");//获取方法返回值类型名称;

11 System.out.print(method[i].getName());//获取方法名称

12 System.out.print("(");13 for(int x = 0; x < p.length;x++){//循环操作参数类型

14 System.out.print(p[x].getSimpleName() +" "+ "arg"+x);//输出参数

15 if(x < p.length -1){//判断是否输出“ , ”

16 System.out.print(",");//输出“ , ”

17 }18 }S19 ystem.out.println();//换行

20 }21 调用类中的方法22 public static void main(String[] args) throwsClassNotFoundException,23 NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,24 InvocationTargetException, InstantiationException {25 //获取类的Class对象

26 Class> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");27 //通过方法名称获取无参Method对象

28 Method me = clazz.getMethod("speak");29 //调用无参构造器创建类对象

30 Object obj =clazz.newInstance()31 me.invoke(obj);32

33

利用反射,在控制台输出以下信息:

public class UserPo{

private int id;

private String userName;

private String userPass;

}

8a7a14d1-7846-47bb-832a-ee357536a4f8.png

注解:

给程序 看的注释,  称为 注解(Annotation)    是代码里的特殊标记,可以在编译,类加载,运行时被读取,并执行相应的处理。 通过使用注解,可以在不改变原有的逻辑的情况下,在源文件嵌入一些补充的信息。

Annotation  提供为程序元素 (包,类,构造器,方法,成员变量,参数,局部变量)设置 元数据的方法 , 它不能运行,只有成员变量,没有方法,跟修饰符一样地位

基本 Annotation :

@Override 限定重写父类方法,如果存在,则正确,反之 ,报错

@Deprecated 表示某个程序或元素 已过时。

@SuppressWaring:抑制编译器警告;

@SafeVarargs:是JDK7专门为抑制“堆污染”警告提供的;

自定义 注解

定义新的Annotation 类型使用@interface 关键字,例如

Public  @interface Table{

}

使用 Annotation   一般会放在另一行,并且放在修饰符之前,如

@Table

public class Myclass{

。。。。

}

成员变量声明

1  无形参的方法

public @interface MyTag {

string name();

int age ();

}

2   指定默认值  在指定成员变量时,使用default 关键字

public @interface MyTag{

string name ()default “ 张三” ;

int age ()  default 18;

}

成员变量的使用方式

1  无形参方法声明时

public class AnnonationTest{

@MyTag ( name = "张三",age=30)

public void info(){

...

}

}

2  默认值声明变量时

public class AnnonationTest{

@MyTag

public void info(){

}

}

Annoation 分类

根据 Annotation 是否包含成员变量, 我们把其分为两类

1  没有成员变量的: 标记Annotation  仅用自身的存在与否提供信息 如重写

2 包含成员变量的: 元数据 Annotation

元注解 (注解的注解)

@Retention  : 用于指定 Annotation 可以保留多长时间

@Target :  指定 Annotation 用于修饰那些元素

@Documented: 用于被修饰的Annotation类将被javadoc工具提取成文档,

默认情况下,javadoc是不包括注解的。

@Inherited:指定Annotation具有继承性;

@Retention(RetentionPolicy.RUNTIME)//元注解

@Target(ElementType.TYPE)//元注解   都是修饰下面的Table 自定义注解的注解

public @interface Table { // 自定义注解

String name();

}

@Column(name = "name")

String name;

@Column(name = "age")

int age;

注解同public 地位一样,同属性绑在一起,可以通过反射Field(属性)操作注解

@Retention

包含一个名为value 的成员变量 , 是RetentionPolicy枚举类型 值如下

RetentionPolicy.SOURCE:Annotation只保留在源代码中,编译器编译时,

直接丢弃这种Annotation;

RetentionPolicy.RUNTIME:编译器把Annotation记录在class文件中。当运行java程序时,JVM会保留该Annotation,程序可以通过反射获取该Annotation的信息;

RetentionPolicy.CLASS:编译器把Annotation记录在class文件中。当运行

java程序时,JVM中不再保留该Annotation;

@Target

包含一个名为“value”的成员变量, 该value成员变量类

型为ElementType[],ElementType为枚举类型, 其值为:

ElementType.TYPE:能修饰类、接口或枚举类型;

ElementType.FIELD:能修饰成员变量;

ElementType.METHOD:能修饰方法;

ElementType.PARAMETER:能修饰参数;

ElementType.CONSTRUCTOR:能修饰构造器;

ElementType.ANNOTATION_TYPE:能修饰注解;

ElementType.LOCAL_VARIABLE:可用于局部变量上

ElementType.PACKAGE:用于记录java文件的package信息

提取Annotation 信息

JDK主要提供两个类, 来完成Annotation的提取:

java.lang.annotation.Annotation接口:所有 annotation 类型都要扩展的公共接口;

java.lang.reflect.AnnotatedElement接口:该接口允许反射性地读取注解。

java.lang.reflect.AnnotatedElement接口

isAnnotationPresent(Class extends Annotation> annotationClass):判断该程序元素上是否存在指定类型的注解,如果存在则返回true,否则返回false;

getAnnotation(Class annotationClass):返回该程序元素上存在的指定

类型的注解,如果该类型的注解不存在,则返回null;

Annotation[] getAnnotations():返回该程序元素上存在的所有注解;

Annotation[] getDeclaredAnnotations() :返回直接存在于此元素上的所有注解。

通过反射取得Annotation

36ea2d9a-eca6-4e65-8f1c-8c171cb0ee02.png

取得指定的Annotation ;

b68af2f3-42e9-4ebe-8a05-33c02200d341.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值