java中的反射详解
- java中的反射详解 推荐度:
- 相关推荐
java中的反射详解
反射
前段时间,网易面试,面试官问我关于反射方面的知识,回答的不是特别好,今天特此补充学习一下~~~
简介
反射是java语言被视为动态或者准动态语言的一个关键性质,这个机制允许程序在运行时通过Reflection API获取任何一个已知名称的class的内部信息,包括修饰符(public static等)、字段或者方法的所有信息、父类以及实现的接口,并可在运行时改变字段的内容或者调用方法。
简单的说,反射机制可以在运行时动态的获取任意一个类的属性和方法,并可以对任意一个属性进行赋值,调用任意一个方法。(即便是私有方法,只要设置setAccessible)
Jdk中的Reflection API
Java反射案例
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的任意一个方法和属性
在使用java反射功能时,首先要获取该类的Class对象,再通过Class对象获取其他对象。
1 获取Class对象
Student s = new Student();
//获取Class对象
//1 getClass方法
Class<?> clazz1 = s.getClass();
System.out.println(clazz1); //class com.wy.reflect.Student
//2 .class语法
System.out.println(Student.class); //class com.wy.reflect.Student
//3 Class.forName()
Class<?> clazz2 = Class.forName("com.wy.reflect.Student"); //class com.wy.reflect.Student
System.out.println(clazz2);
2 获取类的fields
通过反射机制获取某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。
public FieldgetField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口
的指定公共成员字段
public Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class
对象所表示的类或接口的所有可访问公共字段
public FieldgetDeclaredField(Stringname) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类
或接口的指定已声明字段
public Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所
表示的类或接口所声明的所有字段
Field[] fields = clazz1.getFields();System.out.println("---公共成员字段------");for(Field f : fields) {System.out.println(f);}System.out.println("---所有成员字段------");fields = clazz1.getDeclaredFields();for(Field f : fields) {System.out.println(f+" ");}
返回的结果:
---公共成员字段------
public int com.wy.reflect.Student.score
public java.lang.String com.wy.reflect.Person.age
---所有成员字段------
private java.lang.String com.wy.reflect.Student.height
public int com.wy.reflect.Student.score
总结:
getFileds返回的声明为public的属性,包括父类的属性。
getDeclaredFields返回了类中所有的属性,不包括父类的。
3 获取类的Method
通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法。
public Method getMethod(String name,Class
Method[] methods = clazz1.getMethods();System.out.println("---公共成员方法------");for(Method m : methods) {System.out.println(m); //包含父类中public方法}methods = clazz1.getDeclaredMethods();System.out.println("---所有成员方法------");for(Method m : methods) { System.out.println(m); //不包含父类中方法}
输出结果:
—公共成员方法——
public void com.wy.reflect.Student.getScore()
public void com.wy.reflect.Person.getName()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
---所有成员方法------
private void com.wy.reflect.Student.setScore(int)
public void com.wy.reflect.Student.getScore()
private void com.wy.reflect.Student.getHeight()
4 获取类的构造器
通过反射机制获取某个类的构造器,然后调用该构造器创建该类的一个实例。
public Constructor getConstructor(Class
Constructor<?>[] constructors = clazz1.getConstructors();System.out.println("---公共构造方法------");for(Constructor<?> c : constructors) {System.out.println(c); //不包含父类中的构造方法}constructors = clazz1.getDeclaredConstructors();System.out.println("---所有构造方法------");for(Constructor<?> c : constructors) {System.out.println(c); //不包含父类中的构造方法}
结果:
---公共构造方法------
public com.wy.reflect.Student()
---所有构造方法------
public com.wy.reflect.Student()
private com.wy.reflect.Student(java.lang.String)
5 创建类的实例对象
- 调用Class对象的newInstance()方法
该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败。
//有默认构造器,且为public
System.out.println(clazz1.newInstance());
调用默认Constructor对象的newInstance方法
Constructor<?> con = clazz1.getConstructor(); System.out.println(con.newInstance());
调用带参的构造方法
Constructor<?> con2 = clazz1.getConstructor(int.class);
Student stu = (Student) con2.newInstance(12);
System.out.println(stu + " " + stu.score);
注意:这里的构造器方法必须是public
6 调用类的函数
通过反射获取类的Method对象,调用Field的Invoke方法调用函数。
Method setScore = clazz1.getDeclaredMethod("setScore",int.class);Student s = (Student) clazz1.newInstance();//因为setScore是private方法,必须设置为true 表示在反射时取消java语言的反射检查setScore.setAccessible(true);setScore.invoke(s, 100);System.out.println(s.score);
7 设置 获取类的属性值
通过反射获取类的Field对象,调用Field方法设置或获取值
//设置Field f = clazz1.getDeclaredField("height");f.setAccessible(true);f.set(s, "100");//获取System.out.println(f.get(s));
- 互联网是人类历史的一段弯路吗?
- 驱动开发:内核层InlineHook挂钩函数
- 位图BITMAP结构
- 自用
- 《棒球殿堂》:棒球联盟LEAGUE·埼玉西武狮
- python数据写入csv、csv转excel、用Pandas把数据写入excel简单总结
- Java后端学习路线图
- 高并发部署策略 多副本服务+nginx均衡负载
- flink1.14.0+mysql5.7+mysqlcdc2.2.1报错org.apache.flink.shaded.guava18.com.google.common.util.concurren
- 狄利克雷分布通俗讲解
- Hessian矩阵及局部极小点的条件
- 11221
- python thinker(菜单,滚动条,回调函数,对话框)
- java基础面试题 一
- 做外贸怎么起步,从哪里开发客户
- chrome浏览器什么页面都打不开的解决方案
- 视频编解码——编码流程介绍