java反射的用途及实现
一、Java反射框架主要提供以下功能
- 1.在运行时判断任意一个对象所属的类;
- 2.在运行时构造任意一个类的对象;
- 3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
- 4.在运行时调用任意一个对象的方法
二、主要用途
反射最重要的用途就是开发各种通用框架(Spring,hibernate,mybatis)。
三、基本反射功能的实现(反射相关的类一般都在java.lang.relfect包里)
- 1、获得Class对象
- 2、判断是否为某个类的实例
- 3、创建实例
- 4、获取方法
- 5、获取构造器信息
- 6、获取类的成员变量(字段)信息
- 7、调用方法
- 8、利用反射创建数组
通过转载大佬的实例帮助了解:
四、类例
1.hero类
package pojo;
public class Hero {public String name; //姓名public float hp; //血量public float armor; //护甲public int moveSpeed; //移动速度
}
获取类对象有3种方式
1.Class.forName()
2.Hero.class
3.new Hero().getClass()
在一个JVM中,一种类,只会有一个类对象存在(此处准确是在ClassLoader下,只有一个类对象)。所以以上三种方式取出来的类对象,都是一样。
2 .用反射机制创建对象
步骤:与传统的通过new 来获取对象的方式不同反射机制,反射会先拿到Hero的“类对象”,然后通过类对象获取“构造器对象”再通过构造器对象创建一个对象。
1.获取类对象 Class class = Class.forName("pojo.Hero");
2.获取构造器对象 Constructor con = clazz.getConstructor(形参.class);
3 获取对象 Hero hero =con.newInstance(实参)
//这是最简单的获取方法,当Hero的构造方法不是无参构造方法时,获取构造器对象略有不同
给Hero类添加构造方法:
//(默认的构造方法)Hero(String str){System.out.println("(默认)的构造方法 s = " + str);//无参构造方法public Hero(){System.out.println("调用了公有、无参构造方法执行了。。。");}//有一个参数的构造方法public Hero(char name){System.out.println("姓名:" + name);}//有多个参数的构造方法public Hero(String name ,float hp){System.out.println("姓名:"+name+"血量:"+ hp);}//受保护的构造方法protected Hero(boolean n){System.out.println("受保护的构造方法 n = " + n);}//私有构造方法private Hero(float hp){System.out.println("私有的构造方法 血量:"+ hp);}
3.通过反射机制获取对象:
package test;
public class ConstructorTest {/** 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;* 1.获取构造方法:* 1).批量的方法:* public Constructor[] getConstructors():所有"公有的"构造方法public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)* 2).获取单个的方法,并调用:* public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:* public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;* 2.创建对象* Constructor对象调用newInstance(Object... initargs)*/public static void main(String[] args) throws Exception {//1.加载Class对象Class clazz = Class.forName("pojo.Hero");//2.获取所有公有构造方法System.out.println("**********************所有公有构造方法*********************************");Constructor[] conArray = clazz.getConstructors();for(Constructor c : conArray){System.out.println(c);}System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");conArray = clazz.getDeclaredConstructors();for(Constructor c : conArray){System.out.println(c);}System.out.println("*****************获取公有、无参的构造方法*******************************");Constructor con = clazz.getConstructor(null);//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型//2>、返回的是描述这个无参构造函数的类对象。System.out.println("con = " + con);//调用构造方法Object obj = con.newInstance();System.out.println("******************获取私有构造方法,并调用*******************************");con = clazz.getDeclaredConstructor(float.class);System.out.println(con);//调用构造方法con.setAccessible(true);//暴力访问(忽略掉访问修饰符)obj = con.newInstance(100);}
}//总结获取构造器对象方法:1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)2).获取单个的方法:
public Constructor getConstructor(Class… parameterTypes): 获取单个的"公有的"构造方法
public Constructor getDeclaredConstructor(Class…parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
4.获取成员变量并使用
步骤;
1. 获取Hero类的对象
2. 获取属性 Field f1 = h.getDeclaredField("属性名")
3. 修改属性 f1.set(hero,实参),注意这里的hero是对象,不是类对象
Hero hero=new Hero();hero.setName("hero1");try {//获取类HeroPlus的名字叫做name的字段System.out.println("修改前的name:"+hero.name);Field f1= hero.getClass().getDeclaredField("name");//修改这个字段的值f1.set(hero, "hero2");//打印被修改后的值System.out.println("修改后的name:"+hero.name);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}
//修改前的name:hero1
//修改后的name:hero2
//补充:getField和getDeclaredField的区别
//getField只能获取public的,包括从父类继承来的字段。
//getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。
(注:这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
5.获取成员方法并使用
1.获取Hero类的对象
2.获取成员方法:
public Method getMethod(String name ,Class<?>… parameterTypes):
获取"公有方法";(包含了父类的方法也包含Object类)
public Method getDeclaredMethods(String name ,Class<?>… parameterTypes) :
获取成员方法,包括私有的(不包括继承的)
3.参数解释:name : 方法名;Class … : 形参的Class类型对象
4.调用方法(invoke)
Method --> public Object invoke(Object obj,Object… args):
5.参数说明:obj : 要调用方法的对象;args:调用方式时所传递的实参;
Hero hero = new Hero("hero1");try {// 获取这个名字叫做setName,参数类型是String的方法Method m = hero.getClass().getMethod("setName", String.class);System.out.println("修改前"+hero.getName());// 对hero对象,调用这个方法m.invoke(hero, "hero2");// 使用传统的方式,调用getName方法System.out.println("修改后"+hero.getName());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}
//修改前hero1
//修改后hero2
五、Class类方法总结
六、关于反射的用法举例
反射非常强大,但是从上面的记录来看,反而觉得还不如直接调用方法来的直接和方便。
通常来说,需要在学习了Spring 的依赖注入,反转控制之后,才会对反射有更好的理解
。
本文参考
java反射的用途及实现相关推荐
- Java的反射作用_浅析Java 反射机制的用途和缺点
反射的用途 Uses of Reflection Reflection is commonly used by programs which require the ability to examin ...
- java 反射机制性能_Java反射机制的用途和缺点
Java反射机制的用途和缺点 反射的用途 Uses of Reflection Reflection is commonly used by programs which require the ab ...
- Java反射机制的原理和用途
转:https://blog.csdn.net/Appleyk/article/details/77879073 看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依 ...
- Java 反射 (快速了解反射)
反射的概念 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java ...
- java 反射代价_Java反射机制
# 反射 ## 什么是反射 反射是Java提供的动态执行机制, 可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法.. 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行 ...
- 反射 字段_详解面试中常考的 Java 反射机制
反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法. 反射是一项高级 ...
- JAVA 反射知识点总汇
从代码角度,关于反射的用法总结 一.概念 1.1 概念 简单说,JAVA反射机制是指在运行态可直接操作任意类或对象的所有属性和方法的功能,无论他是私有还是public. 1.2 反射的用途 在运行时获 ...
- 使用Java反射更改私有静态最终字段
我有一个带有private static final字段的类,不幸的是,我需要在运行时进行更改. 使用反射我得到此错误: java.lang.IllegalAccessException: Can n ...
- 2018.5.12说说反射的用途及实现------要再花费时间加强理解
说说反射的用途及实现-----https://segmentfault.com/a/1190000013447750?utm_source=tag-newest 说说JAVA的反射机制------ht ...
最新文章
- Java编程思想读书笔记--第21章并发
- java git服务器_windowsServer服务器上搭建GIt服务器
- 图解MyEclipse用DB Browser连接四种数据库
- 解决:SyntaxError: Non-ASCII character ‘\xe8‘ in file 1.py on line 4, but no encoding declared;
- 内存常用的页面调度算法
- 图的遍历[摘录自严长生老师的网站]
- mongodb创建用户名和密码_mongodb用studio3T进行数据备份和用户的创建
- 28. 实现 strStr()---LeetCode---JAVA(今天又是一行超人)
- 一篇文章,带你见证编程语言的诞生!
- 或许是单选的飞鸽传书
- 可见性、原子性和有序性问题
- 三元运算符和if else_PHP If-Else,Switch Case和速记三元运算符示例
- Subversion使用手記
- 端侧机器学习框架 Tensorlfow Lite
- 【Android-混合开发】mPaas-多版本接入篇
- android 桌面操作系统,Android主题美化: Win7桌面完成版Android Seven Pro V2
- html中文字怎么自动排版,CSS网页布局中文字排版九大技巧
- Python,海龟作图,闪避球小游戏
- Linux下EPICS的安装与配置——Phoebus配置与PV连接
- 河南计算机专业考公要求,2017河南公务员专业需求类别(专业分类)