黑马程序员【java中的反射机制】

Java中的反射机制

------- android培训、java培训、期待与您交流! ----------

java的反射机制是java的特性之一,反射机制是构建框架技术的基础所在,使用反射可以使程序更加灵活,避免将程序写死在代码里。相对于很多初学者只接触过java基础的人,反射还是一个很朦胧难懂的概念,下面我们就来说一下反射的一些应用。

java反射机制是指在运行状态中,动态获取信息以及动态调用对象方法的功能。java反射有3个动态性质:1.运行时生成对象实例,2.运行期间调用发放,3.运行时更改属性。

那么反射的原理是什么呢?那我们就要先来看一下java程序的执行过程,想要java程序能够运行,java类必须被java虚拟机加载。运行程序都是在编译时就已经加载了所需要的类。在这里就不得不提一下了,相信很多人对于什么是编译时,什么是运行时还没有一个明确的概念,编译时就是编译器帮你把代码翻译成设备可以识别的代码,也就是说编译器在编译时会做一些简单的工作,比如检查你的语法有没有错误,关键字或者名称书写有无错误,加载类,这都是编译时要做的事情,那运行时都做了什么呢?运行时就是当你的程序开始,代码被装载到内存中后就是运行时,运行时检查就是在你的内存中做操作与判断,下面我们来举个小例子:

   int[] nums = new int[3];
        nums[4] = 12;

很显然,上面这段代码会出现数组下标越界的错误,可是程序在编译时并没有报错,而是在运行时才会报出一个ArrayIndexOutOfBoundsException的错误,这就是编译时和运行时的区别。

而java的反射机制在编译时并不确定是哪个类被加载了,他是在程序运行时候才加载和使用,我们用一张简单的图来看一下反射的执行过程:

Java反射机制能够知道类的基本结构,这种对于java类结构探知的能力成为“自审”,像我们使用eclipse一类软件书写代码时的自动提示功能就是用的java反射的原理。那么通过java的反射,我们可以实现什么功能呢?1.在运行时判断任意一个对象所属类,2.在运行时构造任意一个类的对象,3.在运行时判断任意一个类所具有的属性和方法,4.在运行时调用任意一个对象的方法。java反射常用的类有Class类:反射的核心类,通过Class类可以获取类的属性,方法等内容。Filed类:表示类的属性,可以获取和设置类中属性的值。Method类:表示类的方法,他可以用来获取类中方法的信息,或者执行方法。Constructor类:表示类的构造方法。

好了,我们已经了解了java反射的一些基本信息,下面我们就逐一用代码的方式实现反射的各个功能:

第一个,也是最简单的一个,首先要使用、Class类肯定要先实例化出他,可是Class类没有构造方法,那我们要怎样实例化呢,下面有三种创建Class类的方法:

public static void main(String[] args) {
        //第一种方法,通过对象.getClass()方法
        User user = new User();
        Class<? extends User> cs = user.getClass();
        System.out.println(cs);

        //第二种方法,通过类名.class
        Class<User> cs1 = User.class;
        System.out.println(cs1);

        //第三种方法,通过Class本身的forName()方法,注意forName()方法会抛出一样,并且里面的参数需要完整的包名和类名
        Class<?> cs2 = null;
        try {
            cs2 = Class.forName("cn.fanfu.demo.User");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(cs2);
    }

其中第三种forName()方法可以在类不确定的情况下实例化Class,更具灵活性。

第二个是通过Class类的有参构造创建Class类对象的新实例:

    public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
      //在这里为了更直观的展示,直接使用String类
       Class<?> cs =Class.forName("java.lang.String");
       char[] ch = {‘大‘,‘家‘,‘好‘,‘!‘,‘!‘};
       //调用Class类的有参构造函数,函数里的值为类.class
       Constructor<?> cst = cs.getConstructor(char[].class);
       String name = (String) cst.newInstance(ch);
       System.out.println(name);
       //因为这里的异常会使代码没有直观的显示,所以我直接抛给虚拟机
    }

第三个是取得类的构造、接口、方法、属性等一系列元素:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException {
        //先创建好两个对象
        Class<?> cs = Class.forName("cn.fanfu.demo.User");
        Constructor<?>[] con = null;
        //通过getConstructors()方法返回一个Constructor[]数组,数组里存储的是该类的各个构造
        con = cs.getConstructors();
        for (Constructor<?> item : con) {
            System.out.println(item);
        }
        //通过getInterfaces()方法返回一个Class<?>[]数组,数组里存储的是该类的各个接口
        Class<?>[] inter = cs.getInterfaces();
        for (Class<?> item : inter) {
            System.out.println(item);
        }
        //通过getSuperclass()方法返回一个Class<?>
        Class<?> parent = cs.getSuperclass();
        //java中只支持单继承,所以只有一个父类
        System.out.println(parent);
        //通过getMethods()方法返回一个Method[]数组,数组里存储的是该类的各个方法
        Method[] method = cs.getMethods();
        for (Method item : method) {
            System.out.println(item);
        }
        //通过getDeclaredFields()方法返回一个Field[]数组,数组里存储的是该类的各个属性
        Field[] fiel = cs.getDeclaredFields();
        for (Field item : fiel) {
            System.out.println(item);
        }
        //getDeclaredFields()方法可以获取全部属性,getFields()方法只能获取到公有属性
        Field[] fiel1 = cs.getFields();
        for (Field item : fiel1) {
            System.out.println(item);
        }
    }

第四个是获取或修改类的属性的值:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException, NoSuchFieldException {
        //创建User对象
        User us = new User();
        us.setAge(12);
        us.setName("张三");
        Class<?> cs = us.getClass();
        //获取私有属性的值
        Field fl = cs.getDeclaredField("name");
        //要先设置允许访问
        fl.setAccessible(true);
        //通过get方法指定对象获取值
        String name = (String) fl.get(us);
        System.out.println(name);
        //通过set方法指定对象并修改值
        fl.set(us, "李四");
        String name2 = (String) fl.get(us);
        System.out.println(name2);
    }

第五个是通过反射调用方法:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException, NoSuchFieldException {
        //创建User对象
        User us = new User();
        us.setAge(12);
        us.setName("张三");
        Class<?> cs = us.getClass();
        //通过getMethod()方法获取类中方法,该方法有两个参数,一个指定方法名,一个指定方法中参数的类型
        Method mm = cs.getMethod("say");
        //通过invoke()方法调用方法,该方法有两个参数,一个指定对象,另一个传递参数
        mm.invoke(us);
    }

好了,关于反射的介绍就先这么多了,其他的还有一些列如操作数组集合,都是一些变通用法,就不多做介绍。

时间: 2024-08-03 05:16:24

黑马程序员【java中的反射机制】的相关文章

黑马程序员-java中的反射总结

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- Java 反射总结 类装载器工作机制 类装载器就是寻找类的节码文件并构造出类在JVM 内部表示对象的组件.在Java 中, 类装载器把一个类装入JVM 中,要经过以下步骤: 1.装载:查找和导入Class 文件: 通过一个类的全限定名来获

黑马程序员--Java中的反射逻辑

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 1 .      反射是在运行状态中,对于任意一个类(class文件),都能够知道这个

黑马程序员-Java基础之反射

反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 反射说白了就是可以获得一个类的所有信息,主要包括方法和属性两部分.1.获得方法包括获得方

黑马程序员----Java高新技术之反射学习总结

------- android培训.java培训.期待与您交流! ---------- 反射的概念. 1.Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 精妙的总结就是:反射就是将Java类中的各个成分映射成相应的Java类. 3.在Java中,描述事物的各种类同样也是一种事物,也可以用面向对象的方法来描述,即也有一个类来描述众多的J

黑马程序员————java中的网络编程

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- java中的网络编程 一.网络编程概述:基于互联网的编程 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换. 二.网络模型:OSI和TCP/IP 1.OSI(Open System Interconnection开放系统互连

黑马程序员------Java中GUI(图形用户界面)学习总结

Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! GUI: Graphical User Interface(图形用户接口). 即用图形的方式,来显示计算机操作的界面,以方便用户更容易更直观地操作. Java中为GUI提供的对象都在Java.Awt和Javax.Swing两个包中. java.Awt: Abstract Window ToolKit (抽象窗口工具包). 需要调用本地系统方法实现功能,属于重量级控件. javax.Swing: 在AWT的基础上

黑马程序员------Java中多线程学习总结(一)

Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! 一.多线程的概念 进程:是一种“自包容”的运行程序,有自己的地址空间. 基于进程的特点是允许计算机同时运行两个或更多的程序 线程:是进程内部单一的一个顺序控制流 . 基于线程的多任务处理环境中,线程是最小的处理单位. 在Java中,一个应用程序可以包含多个线程.每个线程执行特定的任务,并可与其他线程并发执行.多线程使系统的空转时间减少,提高了CPU的利用率.多线程编程隐藏了CPU在任务之间切换的事实. 二.创建

黑马程序员------Java中jdk1.5新特性

Java培训.Android培训.iOS培训..Net培训.期待与您交流! JDK1.5新特性: 为什么会出现新特性: 新的技术出现是为了解决老的问题,Java语言为了提高开发者的开发效率,对之前的某些不利于提高效率的技术进行改进. 静态导入: 静态导入:可以导入某个类下的静态方法,静态导入后,可以不写类名而直接使用此类下的静态方法. 语法:import static 包名.类名.静态方法 代码示例: package com.itheima.day1; /** * 静态导入 * @author

黑马程序员-Java中的基本数据类型

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- Java中的数据类型分为两个大类:基本数据类型和引用数据类型. 其中基本数据类型又可以分为四类:整型数据类型,小数数据类型,字符类型,布尔型. 整型数据类型还分为:byte,short,int(整型),long(长整型).默认为int型.

黑马程序员————java中的抽象类

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 抽象类集中的体现了java面向对象的特性,对于每一种事物通过五个方面:属性,方法,构造器,代码块,内部类,来重新解构再进行组装,然后将类似的事物归为一类,这是面向对象的思想.java中常说万物皆对象,那么很显然我们可以进一步的将其中的方法