java反射中的T_Java反射:Web学习的灵魂

075b7e824200bc8f98b4c74a36743e15.png

反射:Web学习的灵魂我们从最初的 javac -HelloWorld.java,到面向对象部分,我们可以将Java代码在计算机中经历的阶段分为三部分:Scource源代码阶段 —— Class类对象阶段 —— Runtime运行时阶段 而我们知道,Java中一个类在源代码阶段,是存储在硬盘中的,而编译后,就已经被加载到内存中区,那么有没有一种方法可以在这种情况下,获取或者修改它的方法或者属性呢?这就是我们今天所讲的Java反射机制

(一) 概述以及好处

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

d71c84868f9d731a60c9496617859523.png

我们将类分为三部分,成员变量,构造方法,成员方法,代码编译后,变成了字节码文件(.class文件)而万物皆对象,所以在字节码文件中,又将这三部分分别整合成对象,所以我们得出结论:

反射:将类的各个组成部分封装成对象,并通过这个Class类型的对象,去使用该文件中的成员变量,构造方法,成员方法

(2) 好处可以在程序“运行时”,对 .class文件进行操作,并且由此获取以及操作 类中的各个部分

可以解耦,提高程序的扩展性

增加程序的灵活性 (最后案例中体现)

(二) 获取Class对象的方式

(1)将字节码文件加载进内存,返回Class对象

多用于配置文件,将类名定义在配置文件中。读取文件,加载类Class.forName("全类名")

(2)多用于参数的传递类名.class

(3)getClass()方法在Object类中定义着

多用于对象的获取字节码的方式对象.getClass():

三种方式的代码实现package cn.ideal.reflect;import cn.ideal.domain.Student;public class ReflectDemo1 {

public static void main(String[] args) throws Exception {

//1.Class.forName("全类名")        Class cls1 = Class.forName("cn.ideal.domain.Student");

System.out.println(cls1);

//2.类名.class        Class cls2 = Student.class;

System.out.println(cls2);

//3.对象.getClass()        Student p = new Student();

Class cls3 = p.getClass();

System.out.println(cls3);

//用 == 比较        System.out.println(cls1 == cls2);//true        System.out.println(cls2 == cls3);//true    }}//运行结果class cn.ideal.domain.Studentclass cn.ideal.domain.Studentclass cn.ideal.domain.Studenttruetrue

通过上面的案例我们可以得出:

**同一个字节码文件(*.class)在一次程序运行过程中,只加载一次,不论通过哪一种方式获取的Class对象都是同一个**

(三) Class对象功能

(1) 获取功能:

获取成员变量们//获取所有public修饰的成员变量Field[] getFields()//获取指定名称的public修饰的成员变量Field getField(String name)   //获取所有的成员变量,不考虑修饰符Field[] getDeclaredFields()  Field getDeclaredField(String name)

获取构造方法们Constructor>[] getConstructors()  Constructor getConstructor(类>... parameterTypes)  Constructor getDeclaredConstructor(类>... parameterTypes)  Constructor>[] getDeclaredConstructors()

获取成员方法们Method[] getMethods()  Method getMethod(String name, 类>... parameterTypes)  Method[] getDeclaredMethods()  Method getDeclaredMethod(String name, 类>... parameterTypes)

获取全类名String getName()

Field:成员变量操作://设置值void set(Object obj, Object value)  //获取值get(Object obj)    //忽略访问权限修饰符的安全检查setAccessible(true):暴力反射

Constructor:构造方法创建对象:T newInstance(Object... initargs)  如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

Method:方法对象//执行方法Object invoke(Object obj, Object... args)  //获取方法名称String getName:获取方法名

我们来具体使用一下上面的一些方法package cn.ideal.reflect;import cn.ideal.domain.Student;import java.lang.reflect.Field;public class ReflectDemo2 {

public static void main(String[] args) throws Exception {

//获取Student的Class对象        Class studentClass = Student.class;

/*            1. 获取成员变量们                * Field[] getFields()                * Field getField(String name)                * Field[] getDeclaredFields()                  Field getDeclaredField(String name)        */

//Field[] getFields() 获取所有public修饰的成员变量        Field[] fields = studentClass.getFields();

for (Field field : fields) {

System.out.println(field);

}

System.out.println("----------");

//Field getField(String name)        Field a = studentClass.getField("a");

//获取成员变量a的值        Student s = new Student();

Object value = a.get(s);

System.out.println(value);

//设置a的值        a.set(s, "张三");

System.out.println(s);

System.out.println("----------");

//Field[] getDeclaredFields() 获取所有的成员变量        Field[] declaredFields = studentClass.getDeclaredFields();

for (Field declaredField : declaredFields) {

System.out.println(declaredField);

}

System.out.println("----------");

//Field getDeclaredField(String name)        Field d = studentClass.getDeclaredField("d");

//忽略访问权限修饰符        d.setAccessible(true);//暴力反射        Object value2 = d.get(s);

System.out.println(value2);

}}//运行结果public java.lang.String cn.ideal.domain.Student.a----------nullStudent{name='null', age=0, a='张三', b='null', c='null', d='null'}----------private java.lang.String cn.ideal.domain.Student.nameprivate int cn.ideal.domain.Student.agepublic java.lang.String cn.ideal.domain.Student.aprotected java.lang.String cn.ideal.domain.Student.bjava.lang.String cn.ideal.domain.Student.cprivate java.lang.String cn.ideal.domain.Student.d----------null

package cn.ideal.reflect;import cn.ideal.domain.Student;import java.lang.reflect.Constructor;public class ReflectDemo3 {

public static void main(String[] args) throws Exception {

//获取Student的Class对象        Class studentClass = Student.class;

/*            2. 获取构造方法们                * Constructor>[] getConstructors()                * Constructor getConstructor(类>... parameterTypes)                * Constructor getDeclaredConstructor(类>... parameterTypes)                * Constructor>[] getDeclaredConstructors()        */

//Constructor getConstructor(类>... parameterTypes)        Constructor constructor = studentClass.getConstructor(String.class, int.class);

System.out.println(constructor);

//创建对象 带参        Object student = constructor.newInstance("张三", 20);

System.out.println(student);

System.out.println("----------");

Constructor constructor1 = studentClass.getConstructor();

System.out.println(constructor1);

//创建对象 不带参        Object student1 = constructor1.newInstance();

System.out.println(student1);

//创建对象 不带参 (推荐方法)        Object o = studentClass.newInstance();

System.out.println(o);

}}

package cn.ideal.reflect;import cn.ideal.domain.Student;import java.lang.reflect.Method;public class ReflectDemo4 {

public static void main(String[] args) throws Exception {

//获取Student的Class对象        Class studentClass = Student.class;

/*            3. 获取成员方法们:                * Method[] getMethods()                * Method getMethod(String name, 类>... parameterTypes)                * Method[] getDeclaredMethods()                * Method getDeclaredMethod(String name, 类>... parameterTypes)        */

//获取指定名称的方法        Method study_method = studentClass.getMethod("study");

Student s = new Student();

//执行方法        study_method.invoke(s);

Method study_method2 = studentClass.getMethod("study", String.class);

//执行方法        study_method2.invoke(s, "英语");

System.out.println("----------");

//获取所有public修饰的方法        Method[] methods = studentClass.getMethods();

for (Method method : methods) {

System.out.println(method);

String name = method.getName();

System.out.println(name);

}

//获取类名        String className = studentClass.getName();

System.out.println(className);

}}

(四) 反射案例

通过修改配置文件,达到不改变该类的任何代码,可以创建任意类的对象,可以执行任意方法,避免了每一次都修改类文件的缺点,同时提高了程序的扩展性* 实现:

1. 配置文件

2. 反射

* 步骤:

1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中

2. 在程序中加载读取配置文件

3. 使用反射技术来加载类文件进内存

4. 创建对象

5. 执行方法

//pro.properties 自定义配置文件className=cn.ideal.domain.StudentmethodName=study

package cn.ideal.reflect;import java.io.InputStream;import java.lang.reflect.Method;import java.util.Properties;public class ReflectTest {

public static void main(String[] args) throws Exception {

/*            不改变该类的任何代码,可以创建任意类的对象,可以执行任意方法         */

//1.加载配置文件

//创建Properties对象        Properties pro = new Properties();

//加载配置文件,转换为一个集合        //获取class目录下的配置文件        ClassLoader classLoader = ReflectTest.class.getClassLoader();

InputStream is = classLoader.getResourceAsStream("pro.properties");

pro.load(is);

//2.获取配置文件中定义的数据        String className = pro.getProperty("className");

String methodName = pro.getProperty("methodName");

//3.加载该类进内存        Class cls = Class.forName(className);

//4.创建对象        Object obj = cls.newInstance();

//5.获取方法对象        Method method = cls.getMethod(methodName);

//6.执行方法        method.invoke(obj);

}

我仅仅浅薄的谈了一下反射的基本知识,一些比较深入的理解由于篇幅问题,放在后面专篇讲解,感谢支持。确实有很多不足之处,也希望能与大家交流。

结尾:

如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !^_^

4a2870206114f6a3bb78d39e441e9831.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值