一,概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

以下主要介绍通过反射获取私有的和公共的构造方法、成员变量、方法;

二,获取任意类的字节码对象的几种方式

Class类:
Class 类的实例对象表示正在运行的 Java 应用程序中的类和接口;也就是jvm中有很多的实例,每个类都有唯一的字节码对象(Class对象);通过唯一的字节码对象就可以反射任意一个类中的构造,成员变量和方法;
Class 类没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机自动构造的;我们不需要创建,JVM已经帮我们创建了;
Class 对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法;

三种方式获取的字节码对象是同一个;


private static void demo1() throws ClassNotFoundException {//第一种Class clazz = Class.forName("com.ang.Teacher");//第二种Class clazz2 = Teacher.class;Teacher t = new Teacher();//第三种Class clazz3 = t.getClass();System.out.println(clazz == clazz2);System.out.println(clazz2 == clazz3);
}

举例

以下是说明反射使用时,用到的被反射对象;

被反射的对象:根据具体情况修改构造类型(私有的:private和公共的:public),各种情况都有注释;

public class Teacher {private String name;private int age;// private Teacher(){
//
//  }public Teacher(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Teacher [name=" + name + ", age=" + age + "]";}private int add(int a,int b){return a+b;}}

三,获取有参,无参构造

获取构造方法步骤

1,首先获取要反射类的字节码对象(Class)

2,通过字节码对象获取有参或无参构造器Constructor

  • 获取public类型有参构造
private static void demo2() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException {Class clazz = Class.forName("com.ang.Teacher");//通过Teacher空参构造创建对象,如果没用空参构造就会报错;而且必须是public类型的空参构造方法;//Teacher t = (Teacher) clazz.newInstance(); //如果没有空参构造或者空参构造是私有的不能使用此方法获取对象//通过有参构造获取对象,有参构造必须是public类型的Constructor c = clazz.getConstructor(String.class,int.class); //获取有参构造器Teacher t = (Teacher) c.newInstance("李四",50);//通过有参构造创建对象System.out.println(t);
}
  • 获取public类型的无参构造
private static void demo3() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException {Class clazz = Class.forName("com.ang.Teacher");Constructor c = clazz.getConstructor();//获取public类型的空参构造Teacher t = (Teacher) c.newInstance();//通过空参构造获取对象t.setAge(40);System.out.println(t);
}
  • 获取私有(private)有参构造
private static void demo6() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException {Class<?> clazz = Class.forName("com.ang.Teacher");Constructor c = clazz.getDeclaredConstructor(String.class,int.class);//获取私有有参构造c.setAccessible(true);//去除私有权限Teacher t = (Teacher) c.newInstance("小高",50);System.out.println(t);
}

四,通过反射获取对象

步骤

1,首先获取要反射类的字节码对象(Class)

2,通过字节码对象的newInstanc()方法获取实例对象;(注意:需要类的无参构造是public或者默认生成的)

  • public构造方法
//通过空参构造获取对象
private static void demo5() throws ClassNotFoundException,InstantiationException, IllegalAccessException {Class<?> clazz = Class.forName("com.ang.Teacher");//空参构造必须是public类型的Teacher t = (Teacher) clazz.newInstance();t.setName("赵敏");System.out.println(t);
}
  • 非public类型构造方法
private static void demo6() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException {Class<?> clazz = Class.forName("com.ang.Teacher");Constructor c = clazz.getDeclaredConstructor(); //获取私有构造,方法参数是可变的,所以有参构造直接传入参数类型的字节码对象;c.setAccessible(true);  //去除私有权限Teacher t = (Teacher) c.newInstance();t.setAge(100);System.out.println(t);
}

五,获取私有成员变量(属性值)并修改和使用

步骤

1,首先获取要反射类的字节码对象(Class)

2,根据反射创建实例

3,通过字节码对象中的getField()或者getDeclaredField()方法获取Field(提供有关类或接口的单个成员变量的信息)

4,通过Field就可以修改和使用成员变量了

  • pubic类型的有参构造是,获取私有成员变量
private static void demo4() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException,NoSuchFieldException {Class<?> clazz = Class.forName("com.ang.Teacher");//通过有参构造获取对象,有参构造必须为public类型Constructor c = clazz.getConstructor(String.class,int.class);//字节码阶段,构造方法的参数只能是字节码对象;Teacher t = (Teacher) c.newInstance("王艳",100); //创建实例对象Field field = clazz.getDeclaredField("name");//获取私有成员变量field.setAccessible(true);//去除私有权限field.set(t, "李代理"); //修改私有成员变量的值System.out.println(t);
}

六,获取私有方法

private static void demo7() throws ClassNotFoundException,NoSuchMethodException, InstantiationException,IllegalAccessException, InvocationTargetException {Class<?> clazz = Class.forName("com.ang.Teacher");Constructor c = clazz.getDeclaredConstructor(); //获取私有无参构造c.setAccessible(true); //去除私有权限Teacher t = (Teacher) c.newInstance();//通过私有构造获取实例Method method = clazz.getDeclaredMethod("add", int.class,int.class);//字节码阶段反射有参方法是,需传入参数类型的字节码method.setAccessible(true);  //去除私有权限int num = (Integer) method.invoke(t, 20,8);System.out.println(num);
}

反射常用的几个类:

1,Class:反射的入口,类的实例表示正在运行的 Java 应用程序中的类和接口。

2,Constructor :提供关于类的单个构造方法的信息以及对它的访问权限。

3,Field :提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。

4,Method :提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。

七,案例

1,通过反射越过泛型检查

private static void demo() throws NoSuchMethodException,IllegalAccessException, InvocationTargetException {List<Integer> list = new ArrayList();list.add(11);list.add(22);Class clazz = list.getClass();Method m = clazz.getMethod("add", Object.class);m.invoke(list, "哈喽");System.out.println(list);
}

打印输出:

[11, 22, 哈喽]  //List泛型指定的是Integer,结果通过反射存入了String

2,通过反射写一个通用的设置某个对象的某个属性为指定的值

package com.ang;import java.lang.reflect.Field;public class Tool {public void setProperty(Object obj,String propertyName,Object values) throws Exception{Class clazz = obj.getClass();Field f = clazz.getDeclaredField(propertyName); //暴力反射获取属性f.setAccessible(true);                          //去除私有权限f.set(obj, values);   //修改属性值}
}
private static void demos() throws Exception {Student s = new Student("张无忌", 40);System.out.println(s);Tool t = new Tool();t.setProperty(s, "name", "赵敏");System.out.println(s);}

打印输出:可以看到,把同一个对象中的属性值修改了

Student [name=张无忌, age=40]
Student [name=赵敏, age=40]

package com.ang;public class Student {private String name;private int age;public Student(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

3, 写一个Properties格式的配置文件,配置指定类的完整名称。再写一个程序,读取这个Properties配置文件,获得类的完整名称并加载这个类,用反射的方式运行run方法。

指定的类:

package com.ang;
public class Animal {public void run(){System.out.println("欢迎来到动物世界。。。");}
}

properties:name.properties配置文件内容

com.ang.Animal

测试类:

public class Test {public static void main(String[] args) {try {BufferedReader br = new BufferedReader(new FileReader("name.properties"));Class clz = Class.forName(br.readLine());Animal a= (Animal) clz.newInstance();a.run();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

运行结果:

欢迎来到动物世界。。。

Java 什么是反射及反射的应用相关推荐

  1. Java、Android基础之—反射

    前言 写这篇文章原因之一,是因为之后会对一些Android第三方框架进行分析.虽不能达到完全清晰,但大体的涉及知识需明白. 反射概述 反射是框架设计的灵魂.(使用的前提条件:必须先得到代表的字节码的C ...

  2. Java中为什么需要反射?反射要解决什么问题?

    Java中为什么需要反射?反射要解决什么问题? 参考文章: (1)Java中为什么需要反射?反射要解决什么问题? (2)https://www.cnblogs.com/buoge/p/9285142. ...

  3. java的准动态(反射)

    java 的反射机制 相关系列 该懂的反射小操作 文章目录 java 的反射机制 相关系列 前言 一.反射机制 二.反射机制的常见操作 java.lang.Class 类 つづく 前言 动态语言 在程 ...

  4. Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  5. java f反射_java反射机制

    反射定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  6. 【重难点】【Java基础 05】说一说你平时遇到的异常、什么情景下会用到反射、反射的底层原理

    [重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 文章目录 [重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 一 ...

  7. java如何用反射把具体方法抽象_如何在Java 中使用泛型或反射机制对DAO进行抽象...

    如何在Java 中使用泛型或反射机制对DAO进行抽象 发布时间:2020-11-26 16:07:42 来源:亿速云 阅读:80 作者:Leah 本篇文章为大家展示了如何在Java 中使用泛型或反射机 ...

  8. Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?

    ava Java 基础这部分一些简单的问题就直接没有放上来. 需要资料的朋友麻烦一键三连之后点此免费获取! 基础: Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)? 谈谈对 ...

  9. Java反射机制(反射Field,Method,Constructor,资源绑定器)

    目录 反射机制 1.反射机制的作用 2.反射机制的相关类在哪个包下 3.反射机制的相关类有哪些 获取Class的三种方式 通过反射实例化对象 通过读属性文件实例化对象 只让静态代码块执行可以使用for ...

  10. JAVA中的糕富帅技术——反射(一)

    前言 突然发现好久没写博客了,前面写的都是关于Android的东西,今天心血来潮突然有一种冲动想写一篇基于JAVA技术的博客,别问我为什么?有钱.任性! 今天就来谈谈反射机制:学过JAVA的人不一定懂 ...

最新文章

  1. SQL SERVER中ROLLUP的用法
  2. showimg.php,layer弹出图片
  3. 高斯计磁场测试仪磁力检测仪磁场测磁仪手持磁通计特斯拉计TD8620
  4. 关于字符串流的学习(c++)
  5. erlang rebar 配置mysql_Erlang Rebar 使用指南之四:依赖管理
  6. 大型网站服务器 pdf,大型网站服务器容量规划[PDF][145.25MB]
  7. android6.0关机动画,安卓系统修改开机动画,关机动画
  8. 漏洞payload 靶机_学生会私房菜【20200707期】Wordpress 4.6 任意命令执行漏洞
  9. hrbp 牵着鼻子走_防止被下属牵着鼻子走的四个经典方法,学会了,下属就好管了...
  10. matlab显示灰度值的概率,求Matlab统计灰度值的代码
  11. spark与Hive的整合入门
  12. windows环境tomcat8配置Solr5.5.1
  13. 航海王启航服务器维护要多久,《航海王启航》7月1日服务器更新维护公告
  14. 网站访问计数器 php,用PHP生成访客计数器
  15. win10系统Qt配置海康HCSadpSDK局域网设备搜索
  16. SPSS新手教程——进行距离分析的方法
  17. Xprinter XP-N160L 打印机驱动
  18. idea时间重置插件
  19. Android 4.2官方文档chm格式下载
  20. PC端js禁止浏览器缩放

热门文章

  1. 如何将爬取的数据存入数据库中
  2. PHP CURL解决 此图片来自QQ微信公众平台,未经允许不可引用
  3. 到月宫上挖土-嫦娥五号背后的航天系统工程
  4. 超详细的MySQL入门教程(三)
  5. 【转】酒桌上经典劝酒词
  6. 混合云是什么,混合云是怎么工作的?
  7. 什么是uni-app?
  8. 批量论文自动下载——从dblp数据库中查找并爬取论文
  9. python获取文件的绝对路径
  10. 不讲武德,Kubernetes 弃用 Docker刷爆了网络,我们公司也慌了!