反射

前段时间,网易面试,面试官问我关于反射方面的知识,回答的不是特别好,今天特此补充学习一下~~~

简介

反射是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));

java中的反射详解相关推荐

  1. Java中JDBC连接数据库详解

    今天动力节点java学院小编分享的是JDBC连接数据库的相关知识,希望通过看过此文,各位小伙伴对DBC连接数据库有所了解,下面就跟随小编一起来看看JDBC连接数据库的知识吧. 一.JDBC连接数据库概 ...

  2. JAVA中的Random详解

    JAVA中的Random详解 首先,在JDK自带的常用的random中有两个,这俩都是产生随机数的,不过一个是util下的random,另外一个是Math下的.我们分别介绍一下 util中的rando ...

  3. java中new关键字详解

    java中new关键字详解 在java中我们可以经常使用new来创建一个对象,但是这对于初学者来说可能只会使用却不能理解new关键字和它的语法 new关键字的语法 注意使用前先导包,一般我们使用ide ...

  4. Java中super关键字详解

    Java中super关键字详解 super有什么用? super什么时候不可以省略呢? super在内存图中是如何存在的呢? super使用时的注意事项 super有什么用? (1)当子类中构造方法第 ...

  5. Java中的byte详解

    Java中的byte详解 介绍 byte,即字节,由8位的二进制组成.在Java中,byte类型的数据是8位带符号的二进制数. 在计算机中,8位带符号二进制数的取值范围是[-128, 127],所以在 ...

  6. Java中Iterator迭代器详解

    目录 一.Java中Iterator迭代器详解 1.为什么需要迭代器 2.迭代器长什么样子 3.如何使用迭代器 使用步骤: 代码演示: 迭代器可以简化为增强型for循环: 4.Iterator与Lis ...

  7. Java 中IO流详解(附实例代码/面试题)

    Java I/O流详解 前言 一.I/O流是什么? 二.IO流分类: 1. 流程图: io流对象 2. io流的优缺点: 3. io 流Java中用途有哪些? 三.一些 io 实例 四.面试题: 前言 ...

  8. 【转载】java中泛型使用详解

    引入 Type接口 Class类 Method类 Field类 ParameterizedType接口 TypeVariable接口 类中定义泛型变量 方法中定义泛型变量 方法中泛型参数和泛型返回值 ...

  9. java 中的vector_详解Java中的Vector

    Vector实现了AbstractList抽象类和List接口,和ArrayList一样是基于Array存储的 Vector 是线程安全的,在大多数方法上存在synchronized关键字 //Vec ...

最新文章

  1. python写一个文件下载器_Python3使用TCP编写一个简易的文件下载器
  2. 《预训练周刊》第13期:CPM-2:大规模经济高效的预训练语言模型、变换器作为编程语言...
  3. linux 关机 日志,centos7 异常关机了,怎么查看系统的异常日志?
  4. 2019 年编写现代 JavaScript 代码的5个小技巧
  5. 透视转换oracle,使用Oracle的行列转化函数实现ASH的数据透视功能
  6. android自定义ClockView
  7. oracle实现累加,oracle用sum函数实现累加
  8. Android取手机号码
  9. 服务器与交换机的lacp协议,IEEE 802.3ad 链路聚合与 LACP 的简单知识 EtherChannel 总结...
  10. 速达3000数据库结构; 怎么查看速达5000工业版数据库结构
  11. 渗透工具——Namp基础用法
  12. 【深度学习】空洞卷积(Atrous Convolution)
  13. Linux环境下命令行下载DM8
  14. 5款非常好用的免费数据库建模工具(免费)
  15. android数据线接口分类,安卓手机数据线接口类型
  16. mac os x 使用教程_如何在Mac OS X计算机上使用扫描仪
  17. 中兴通讯专利技术价值超450亿元
  18. 姓名转拼音的几种格式
  19. 【音频处理】视频加速音频不变调
  20. 机器学习 day5 day6 分类问题实战:判断是否为羊毛党

热门文章

  1. 数据库概论学习笔记——关系数据理论
  2. 电波传播基础公式总结
  3. 从“为什么创业”到“怎么创业”(转)
  4. 如何将文字转图片?手把手教你转换
  5. 图片img标签设置默认图片
  6. hackthebox-Tracks-Beginner_Track-Lame
  7. 启动牛市的密钥藏宝计划(TPC),火热来袭!
  8. HDU 3518 HDU 4416【后缀自动机len的使用】
  9. 分治法:快速排序棋盘覆盖
  10. Linux | 文件类型说明