java反射原理,应用
java类的加载过程
调用java命令运行程序时,该命令会启动一条java虚拟机进程,该程序的所有线程都会运行在这个虚拟机进程里面。程序运行产生的线程、变量都处于这个进程,共同使用该JVM进程的内存区。
类加载过程
当程序调用一个类的时候,该类的class文件会被读入到内存中,用一个数组存放,产生一个对应的类对象。此时class还不可使用。而后开始检查该class文件是否正确,然后给类中的静态变量分配储存空间。最后对静态对象和静态代码块执行初始化工作。
如果该类存在父类。而且没有被加载,那么就会先加载初始化父类。并且先执行类中的初始化语句。
反射
反射就是在class文件被加载到JVM的时候进行操作的。因为java类被编译为class文件。所以使用反射获取class文件从而拿到java类的所有信息。
即:java类中的所有元素,包括属性,方法,都会被看做一个对象。
如何获取class的对象
java是面向对象语言,万事万物皆为对象。即所有类也是一个对象。是lang包下的Class类的对象:java.lang.Class的对象。
有三种获得方式:
1、通过对象类的对象获取
//首先创建类的对象 Stu stu = new Stu();
在不知道类名的情况下,传入一个对象,可以使用getClass()方法获得类名
//class获取该类 Class getclass = stu.getClass();
2、通过类名获取
//跳过对象类创建对象的过程 Class getclass = Stu.class;
3、通过类名获取,但是会有异常抛出,并且需要强转类型
最常用
try{
Class getclass = (Class) Class.forName("Stu");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
通过类的对象获取属性,方法
此时需要调用Method类:(以下为Api内容)
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出 IllegalArgumentException。
首先:获得该类的所有成员方法,接上文的Class对象getClass
getMethods() :方法是获得类所有的public方法。
Method[ ] methods = getclass.getMethods();
getDeclareMethods() : 方法是获得类所有方法,不考虑权限。但是不包括父类继承的方法。
Method[ ] methods = getclass.getDeclareMethods();
开发尽量少用继承
遍历集合:getReturnType() : 得到方法的返回值类型
getName() : 得到方法名
先获取类型,再获取方法名
Class returnType = methods[ i ].getReturnType();
String returnTypeName = returnType.getName();
现在拿到了方法的返回值类型,方法名,还需要方法的参数列表,因为一个方法的参数列表可能有多个,所以需要先得到参数列表的集合,遍历得到单个参数类型
public Class<?>[ ] getParameterTypes()
按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。如果底层方法不带参数,则返回长度为 0 的数组。
返回:此对象所表示的方法的参数类型 (来自Api)
Class[ ] paramTypes = methods[ i ].getParameterTypes();
由:paramTypes[ i ].getName(); 得到参数类型名。
参数名由Java8提供的Parameter类可以得到参数名。
Parameter[ ] parameters = method[ i ].getParameters();
遍历该集合可以得到参数名----一般编译器默认不编译参数名的,所以可能获得的是arg0;
//参数类型 String Type = parameters[ i ].getType().toString();
//参数名 String name = parameters[ i ].getName();
获取成员变量
方法是Method类的对象,成员变量是Field类的对象。
getFields() : 获得所有公有成员变量
getDeclaredFields() : 获得所有自己声明的成员变量,不考虑权限,,但是不包括父类继承的。
Fields[ ] fields = getclass.getFields();
getType() : 获得成员变量的类型
getName() : 获得成员变量名
String name = fields[ i ].getType().getName();
获取构造函数
构造函数是Constructor类的对象;
//获得构造函数集合 区别同上
Constructor[] constructors1 = class1.getConstructors();
Constructor[] constructors2 = class1.getDeclaredConstructors();
遍历得到类型:
for (Constructor constructor : constructors2) {
Class[] paramTypes = constructor.getParameterTypes();
for (Class paramType : paramTypes) {
String paramTypeName = paramType.getName();
}
}
通过反射调用方法
获取类类型,然后获取方法类型
try{
Class getclass = (Class) Class.forName("Stu");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第一个参数表示方法名,后面依次为方法的参数类型,没有则不传
Method[ ] methods = getclass.getMethod(" FunctionName ", FunctionType)
methods.function(类对象,方法参数)
eg:
类方法
public class Stu {
public void add (int a,int b){ return a+b;}
}
获取类对象,获取方法,调用方法
Stu stu = new Stu();
try{
Class getclass = (Class) Class.forName("Stu");
Method func = getclass.getMethod("add",int.class,int.claaa);
func.add(stu,2,3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
- public class User {
- private int id;
- private String name;
- public String addr;
- private void speak(int a,int b){
- System.out.println("私有方法");
- }
- public void eat(String a){
- System.out.println("公有方法");
- }
- public int run(Boolean a){
- System.out.println("共有有返回值方法");
- return 4;
- }
- public User(int id, String name, String addr) {
- this.id = id;
- this.name = name;
- this.addr = addr;
- }
- }
JavaBean
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- public class Test {
- public static void main(String[] args) throws ClassNotFoundException {
- //拿到对象
- Class clazz = Class.forName("User");
- //通过对象拿类的方法,属性
- //拿到所有共有方法
- Method[] getMethon1 = clazz.getMethods();
- for (Method method : getMethon1) {
- System.out.println("打印共有方法名:"+method.getName());
- System.out.println("打印共有方法返回值类型:"+method.getReturnType());
- Class[] funcType = method.getParameterTypes();
- for (Class aClass : funcType) {
- System.out.println("打印该方法的参数类型列表: "+aClass.getTypeName());
- }
- }
- System.out.println("-----------------------------------");
- //获得该类自己创建的方法
- Method[] getMethon2 = clazz.getDeclaredMethods();
- for (Method method : getMethon2) {
- System.out.println("打印所有创建方法名:"+method.getName());
- System.out.println("打印所有创建方法返回值类型:"+method.getReturnType());
- Class[] funcType2 = method.getParameterTypes();
- for (Class aClass : funcType2) {
- System.out.println("打印该方法的参数类型列表: "+aClass.getTypeName());
- }
- }
- //拿到公有成员变量
- Field[] fields = clazz.getFields();
- for (Field field : fields) {
- System.out.println("打印该变量的变量名:"+field.getName());
- System.out.println("打印该变量的类型:"+field.getType());
- }
- //拿到该类创建的成员变量
- Field[] fields1 = clazz.getDeclaredFields();
- for (Field field : fields1) {
- System.out.println("打印该变量的变量名:"+field.getName());
- System.out.println("打印该变量的类型:"+field.getType());
- }
- //拿到构造函数
- Constructor[] constructors = clazz.getConstructors();
- for (Constructor constructor : constructors) {
- System.out.println("打印构造方法的名 : "+constructor.getName());
- //拿到构造方法的参数列表
- Class[] funcTypeCons = constructor.getParameterTypes();
- for (Class funcTypeCon : funcTypeCons) {
- System.out.println("打印参数类型:"+funcTypeCon.getTypeName());
- }
- }
- }
- }
- 打印共有方法名:run
- 打印共有方法返回值类型:int
- 打印该方法的参数类型列表: java.lang.Boolean
- 打印共有方法名:eat
- 打印共有方法返回值类型:void
- 打印该方法的参数类型列表: java.lang.String
- 打印共有方法名:wait
- 打印共有方法返回值类型:void
- 打印共有方法名:wait
- 打印共有方法返回值类型:void
- 打印该方法的参数类型列表: long
- 打印该方法的参数类型列表: int
- 打印共有方法名:wait
- 打印共有方法返回值类型:void
- 打印该方法的参数类型列表: long
- 打印共有方法名:equals
- 打印共有方法返回值类型:boolean
- 打印该方法的参数类型列表: java.lang.Object
- 打印共有方法名:toString
- 打印共有方法返回值类型:class java.lang.String
- 打印共有方法名:hashCode
- 打印共有方法返回值类型:int
- 打印共有方法名:getClass
- 打印共有方法返回值类型:class java.lang.Class
- 打印共有方法名:notify
- 打印共有方法返回值类型:void
- 打印共有方法名:notifyAll
- 打印共有方法返回值类型:void
- -----------------------------------
- 打印所有创建方法名:run
- 打印所有创建方法返回值类型:int
- 打印该方法的参数类型列表: java.lang.Boolean
- 打印所有创建方法名:speak
- 打印所有创建方法返回值类型:void
- 打印该方法的参数类型列表: int
- 打印该方法的参数类型列表: int
- 打印所有创建方法名:eat
- 打印所有创建方法返回值类型:void
- 打印该方法的参数类型列表: java.lang.String
- 打印该变量的变量名:addr
- 打印该变量的类型:class java.lang.String
- 打印该变量的变量名:id
- 打印该变量的类型:int
- 打印该变量的变量名:name
- 打印该变量的类型:class java.lang.String
- 打印该变量的变量名:addr
- 打印该变量的类型:class java.lang.String
- 打印构造方法的名 : User
- 打印参数类型:int
- 打印参数类型:java.lang.String
- 打印参数类型:java.lang.String
测试结果
java反射原理,应用的更多相关文章
- JAVA反射原理
什么是反射? 反射,一种计算机处理方式.是程序可以访问.检测和修改它本身状态或行为的一种能力.java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等.除了 ...
- [转]Java Spring的Ioc控制反转Java反射原理
转自:http://www.kokojia.com/article/12598.html 学习一个东西的时候,如果想弄明白,最好想想框架内部是如何实现的,如果是我做我会怎么实现.下面我就写一个Ioc ...
- JAVA反射原理解读
一.什么是JAVA的反射 1.在运行状态中,对于任意一个类,都能够知道这个类的属性和方法. 2.对于任意一个对象,都能够调用它的任何方法和属性. 这种动态获取信息以及动态调用对象的方法的功能称为JAV ...
- 深入理解java反射原理
反射是java的一个特性,这一特性也使得它给了广大的第三方框架和开发过者很大的想像空间. 通过反射,java可以动态的加载未知的外部配置对象,临时生成字节码进行加载使用,从而使代码更灵活!可以极大地提 ...
- 【反射】利用java反射原理将xml文件中的字段封装成对应的Bean
本例使用的xml解析方式为jdom ... <ROOT> <Consignment> ... </Consignment> </ROOT> 解析xml文 ...
- java 反射原理写了一个赋值和取值通用类
首先了解一下反射的原理,什么是反射?所谓的反射就是指java 语言在运行时拥有一项自观的能力,反射能使你得到装载到 jvm 中的类的内部信息,它不需要你在编码的时候就知道所需类的内部信息,允许程序执行 ...
- java反射原理运用
1.首先用Java反射机制的要做到的一个目的:我们都知道通过得到一个对象中的指定方法或者属性等,基于这个原理我们来做一个 通用的功能,让客户端可以通过传入的对象和一个标识去调用这个对象里自己想要的方法 ...
- Java 反射原理
一.Java 反射的定义 反射机制是在运行状态中, 对于任意一个类, 都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法或者属性: 二.反射提供的功能: 在运行时判断任意 ...
- Java反射原理和实际用法
背景 反射在Java中非常重要,是Java区别于其他编程语言的一大特性.Java中的AOP切面.动态代理等看起来像黑魔法一样的技术,就离不开反射.字节码等.这些技术能在不侵入原有代码的情况下,做一些增 ...
随机推荐
- Maven多模块项目打包前的一些注意事项(打包失败)
一. 最近在打包Maven项目时遇到了点问题,这个项目是Maven多模块项目,结构如下: projectParent├── xxxx-basic├── xxxx-web1├── xxxx-collec ...
- Springmvc的运行原理 SpringMvc的优点
SpringMVC框架运行原理 1:客户端发送请求到前端控制器(DispatcherServlet),前端控制器根据请求信息(url),查询一个或多个HandlerMapping, 前端控制器,来决定 ...
- 网编(小白心得osi七层协议)
目录 1 C/S B/S架构 2网络通信原理 3osi七层协议 数据链路层 网络层 传输层 应用层 1 C/S B/S架构 C:client端(客户端) B:browse 浏览器 S: s ...
- R 实用命令 1
Quit and restart a clean R session from within R? If you're in RStudio: command/ctrl + shift + F10 . ...
- 网页如何设置favicon.ico
1.首先制作ico图,并命名favicon.ico 2.将文件放在项目的根目录下
- 《白帽子讲web安全》——吴瀚清 阅读笔记
浏览器安全 同源策略:浏览器的同源策略限制了不同来源的“document”或脚本,对当前的“document”读取或设置某些属性.是浏览器安全的基础,即限制不同域的网址脚本交互 <scr ...
- Flutter学习笔记(23)--多个子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)
如需转载,请注明出处:Flutter学习笔记(23)--多个子元素的布局Widget(Rwo.Column.Stack.IndexedStack.Table.Wrap) 上一篇梳理了拥有单个子元素布局 ...
- odoo添加顶部按钮实现自定义方法
一.效果图 自定义添加顶部按钮,实现自定义方法. 二.实现过程 1.需要用到三个文件,tree_view_button.js.tree_view_odoo.xml.base.xml三个文件,文件目录如 ...
- unity_小功能实现(碰撞检测)
1.触发器Trigger:勾选IsTrigger属性 //当player刚进入触发区域的时刻发生触发检测,比如在靠近门的某个区域门一直处于开着状态 void OnTriggerEnter(Collid ...
- unity_小功能实现(客户端相互通信功能)
服务器端:在VS中新建项目,用于服务器的搭建 using System;using System.Collections.Generic; using System.Net.Sockets;u ...