Java反射机制学习
来源:互联网 发布:linux awk 函数 编辑:程序博客网 时间:2024/05/21 17:06
Java反射机制学习
一、定义
反射机制是在运行状态中,对于任意一个类,都能获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
二、用途
- 运行时获取任意一个对象所属的类;
- 运行时动态生成任意一个类的对象;
- 运行时获取任意一个类所具有的字段和方法;
- 运行时动态调用任意一个对象的方法;
- 运行时获取注解信息;
- 生成动态代理
三、具体功能实现
1、准备工作
为了更好的介绍反射机制功能的实现,我们先定义了一些类作为分析对象,利用它们进行更好的说明,如下:
首先,是我们自己定义了一些注解:
//用于注解类@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface ClassAnno {}//用于注解变量@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface FieldAnno { String name() default "sfw";}//用于注解方法@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MethodAnno {}//用于注解方法的参数@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface ParaAnno {}//用于注解方法的d参数@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface ParaAnno {}
然后,定义了一些类,用于说明反射机制。
interface Animal {}class Person implements Animal { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }}@ClassAnnoclass Student extends Person { @FieldAnno public String name; @FieldAnno private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } @MethodAnno public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @MethodAnno public void setNameAndAge(@ParaAnno @ParaAnno2 String name, @ParaAnno @ParaAnno2 int age) { this.setName(name); this.setAge(age); } private void ceshi(){ System.out.println("private方法调用"); }}
好了,接下来正式进行反射机制的分析:
2、获取Class对象
在反射中,常用的获取Class对象的方法有三种
(1) 通过类的对象调用getClass()方法的方式:
Class pClass1 = person.getClass();
(2) 通过Class类的静态方法forName():
Class pClass2 = null;pClass2 = Class.forName("com.sfw.anno.reflectiondemo.Person");
注:forName方法的参数必须为完全限定类名(包名+类名)。
(3) 通过类字面常量获得:
Class pClass3 = Person.class;
类字面常量不仅可以应用于普通的类、接口、数组、基本数据类型。
(4) 基本数据类型也可以通过TYPE字段获得:
Class longClass2 = Long.TYPE;
Java中常用的基本数据类型和TYPE的对应关系:
3、通过Class对象获取类名
常用的有两个方法:
4、通过Class对象获取类修饰符
获取类的public、private、static等修饰符的方法:
int modifiers = pClass1.getModifiers();
getModifiers()方法的返回值是int类型,每种修饰符就是这个返回值的其中一位,如果对应位为1,则表示这个类包含这个修饰符。
常用修饰符、对应位、修饰符是否使用方法对应关系如下:
5、通过Class对象获取类的包信息
通过getPackage()方法获取指定类的包信息:
Package pkg = pClass1.getPackage();String packageName = pkg.getName();
6、通过Class对象获取父类
通过getSuperclass()方法获取指定类的的父类:
Class studentClass = Student.class;Class superStudentClass = studentClass.getSuperclass();
7、通过Class对象获取类实现的接口
getInterfaces()方法获取类实现的接口,返回值是一个Class数组,即类可能实现多个接口。
Class[] interfaces1 = pClass1.getInterfaces();Class[] interfaces2 = studentClass.getSuperclass().getInterfaces();
8、通过Class对象获取类构造器生成实例
- 获取类无参数构造器并生成实例:
Constructor constructor1 = studentClass.getConstructor();Student student1 = (Student) constructor1.newInstance();
- 获取类有参数构造器并生成实例:
Constructor constructor2 = studentClass.getConstructor(String.class, int.class);Student student2 = (Student) constructor2.newInstance("sfw", 27);
9、通过Class对象获取类的方法
获取所有public方法,包括子类和父类的public方法:
Method[] methods1 = studentClass.getMethods();
获取指定的public方法:
Method method1 = studentClass.getMethod("setAddress", String.class);
调用参数为空的public方法:
Method getage = student2.getClass().getMethod("getAge");int age = (int) getage.invoke(student2);
调用多参数的public方法:
Method setNameAndAge = student2.getClass().getMethod("setNameAndAge", String.class, int.class);setNameAndAge.invoke(student2, "wsf", 18);
获取方法的参数类型
Class[] paraTypes = setNameAndAge.getParameterTypes();
获取本类所有方法
Method[] declaredMethods = student2.getClass().getDeclaredMethods();
调用本类方法,如果方法为private,需要调用setAccessible(true)后,才能调用。
Method ceshi =student2.getClass().getDeclaredMethod("ceshi");ceshi.setAccessible(true);ceshi.invoke(student2);
10、变量
获取所有public变量,包括本类和父类的public变量:
Field [] fields = student2.getClass().getFields();
获取指定public变量,并设置变量值,读取变量值:
Field field = student2.getClass().getField("name");field.set(student2,"shufengwu");String name = field.get(student2);
获取本类变量,包括私有变量,访问私有变量调用setAccessible(true):
Field[] declaredFields = student2.getClass().getDeclaredFields();for (Field declaredField:declaredFields){ field.setAccessible(true); System.out.println(declaredField.getName());}
获取本类指定变量:
Field declaredField = student2.getClass().getDeclaredFields("age");
11、获取注解
获取类上注解:
Annotation [] annotations = Student.class.getAnnotations();
获取类上指定注解:
ClassAnno classAnno = Student.class.getAnnotation(ClassAnno.class);
获取指定字段上指定注解及参数值:
FieldAnno fieldAnno = Student.class.getField("name").getAnnotation(FieldAnno.class);System.out.println(fieldAnno +" "+ fieldAnno.name());
获取指定方法的注解:
Method method = Student.class.getMethod("setNameAndAge",String.class,int.class);MethodAnno methodAnno = method.getAnnotation(MethodAnno.class);System.out.println(methodAnno);
获取指定方法的参数的注解:
Method method = Student.class.getMethod("setNameAndAge",String.class,int.class);//一个方法可能有多个参数,一个参数可能有多个注解Annotation[][] parameterAnnotations = method.getParameterAnnotations();//遍历每个参数for (int i=0;i<parameterAnnotations.length;i++){ Annotation[] annotations2 = parameterAnnotations[i]; //遍历参数的每个注解 for (int j = 0;j<annotations2.length;j++){ System.out.print(annotations2[j]+" "); } System.out.println();}
点击此处获取使用例程
参考文献
【1】 Java反射机制详解
http://baike.xsoftlab.net/view/209.html#1
【2】 Java反射详解
http://blog.csdn.net/a15286856575/article/details/53330821?locationNum=1&fps=1
- java反射机制学习
- JAVA反射机制学习
- Java反射机制学习
- JAVA反射机制学习
- java反射机制学习
- java反射机制学习
- java反射机制学习
- Java反射机制学习
- Java学习 反射机制
- Java反射机制学习
- java反射机制学习
- java反射机制学习
- Java学习:反射机制
- Java反射机制学习
- Java反射机制学习
- Java反射机制学习
- java 反射机制学习
- java 反射机制学习
- android中用ExpandableListView实现三级扩展列表(附源码)
- 分布式存储--Mysql--序列1--聚簇索引&非聚簇索引
- POJ-----1006---Biorhythms扩展欧几里得
- Clone Graph
- VMware虚拟机中的3种网络连接的模式
- Java反射机制学习
- Android仿IOS级联菜单_ListView实现区域级联选择效果
- Android仿IOS级联菜单_ListView实现区域级联选择效果
- 功能全面的电商微信小程序源码下载
- Android-PickerView
- Android:学习AIDL,这一篇文章就够了(上)
- yarn依赖管理工具的使用
- Android:学习AIDL,这一篇文章就够了(下)
- 2016/11/27