Java—反射
Posted 超霸霸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java—反射相关的知识,希望对你有一定的参考价值。
反射
一、概念
- 框架:半成品软件,可以在框架的基础上进行软件开发,简化编程
- 反射:将类的各个组成部分封装为其他对象,这就是反射机制
- 好处:
- 可以在程序运行过程中操作这些对象
- 可以解耦,提供程序的可扩展性
二、class对象
-
获取class对象的方式
-
Class.forName("全类名")
:将字节码文件加载进内存,返回Class对象- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
-
类名.class
:通过类名的属性class获取- 多用于参数的传递
-
对象.getclass()
:getclass()方法在object类中定义者- 多用于对象的获取字节码的方式
-
同一个字节码文件(*.class)在一次程序运行过程中,只会加载一次,不论通过哪一种方式获取的class对象都是同一个
//1.Class.forName("全类名") Class cls1=Class.forName("cn.chao.web.domain.person"); System.out.println(cls1); //2.类名.class Class cls2= person.class; System.out.println(cls2); //3.对象.getClass() person p=new person(); Class cls3=p.getClass(); System.out.println(cls3);
-
-
class对象功能
-
获取成员变量
Field[] getFields()
:获取所有public修饰的成员变量Field[] getField(String name)
:获取指定名称的public修饰的成员变量Field[] getDeclaredFields()
:获取所有的成员变量,不考虑修饰符Field[] getDeclaredField(String name)
- 操作:
- 设置值:
void set(Object obj, Object value)
- 获取值:
get(Object obj)
- 忽略访问权限修饰符的安全检查:
setAccessible(true)
暴力反射
- 设置值:
//获取所有public成员变量 Class personClass= Person.class; Field[] fields=personClass.getFields(); for(Field field:fields) System.out.println(field); System.out.println("---------"); Field a=personClass.getField("a"); //获取public成员变量a的值 Person p=new Person(); Object value=a.get(p); System.out.println(value); //设置a的值 a.set(p,2); System.out.println(p); System.out.println("---------"); //获取所有成员变量 Field[] declaredfields=personClass.getDeclaredFields(); for(Field field:declaredfields) System.out.println(field); System.out.println("---------"); //获取私有成员变量id的值 Field id=personClass.getDeclaredField("id"); //忽略访问权限修饰符的安全检查 id.setAccessible(true);//暴力反射 Object value2=id.get(p); System.out.println(value2);
-
获取构造方法
Constructor<?>[] getConstructors()
Constructor<T>[] getConstructor(类<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor<T>[] getDeclaredConstructor(类<?>... parameterTypes)
- 如果使用空参构造方法创建对象,操作可以简化:
Class对象的newInstance方法
- 执行方法:
Object invoke(Object obj, Object... args)
- 获取方法名:
String getName()
Class personClass = Person.class; //获取指定构造器 Constructor constructor=personClass.getConstructor(String.class,String.class); System.out.println(constructor); //创建对象 Object person=constructor.newInstance("chao","asd"); System.out.println(person); System.out.println("--------"); //空参 Constructor constructor1=personClass.getConstructor(); System.out.println(constructor1); //1 Object person1=constructor1.newInstance(); System.out.println(person1); //2 Object person2=personClass.newInstance(); System.out.println(person2); System.out.println("--------");
-
获取成员方法
Method[] getMethods()
Method[] getMethod(String name,类<?>... parameterTypes)
Method[] getDeclaredMethods()
Method[] getDeclaredMethod(String name,类<?>... parameterTypes)
Class personClass = Person.class; //获取指定名称的方法 Method eat_method=personClass.getMethod("eat"); Person p=new Person(); //执行方法 eat_method.invoke(p); System.out.println("-----------"); //获取带参指定名称的方法 Method eat_method2=personClass.getMethod("eat",String.class); //执行方法 eat_method2.invoke(p,"shit"); System.out.println("-----------"); //获取所有public修饰的方法 Method[] methods=personClass.getMethods(); for(Method method:methods) String name=method.getName(); System.out.println(name); System.out.println("-----------");
-
获取类名
String getName()
-
三、案例
-
需求:写一个“框架”,不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
-
实现:
- 配置文件
- 反射
-
步骤:
- 将需要创建的对象的全类名和需求执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建方法
- 执行方法
-
pro.properties文件:
className=cn.chao.web.domain.Person
methodName=walk
- reflectTest文件:
package cn.chao.web.reflect;
import java.io.IOException;
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.加载配置文件
//1.1创建Properties对象
Properties pro=new Properties();
//1.2加载配置文件,转换为一个集合
//1.2.1获取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);
以上是关于Java—反射的主要内容,如果未能解决你的问题,请参考以下文章