【JAVA反射机制】
一、Class类
Java.lang.Object
|-java.lang.Class<T>
构造方法:无。
常用方法:
|
|
|
|
getConstructor |
|
|
Constructor |
getConstructors |
|
getDeclaredConstructor |
|
|
|
getDeclaredConstructors |
|
getDeclaredField |
|
|
|
getDeclaredFields |
|
getDeclaredMethod |
|
|
|
getDeclaredMethods |
|
getField |
|
|
|
getFields |
|
getMethod |
|
|
|
getMethods |
|
newInstance |
二、Constructor
Java.lang.Object
|-java.lang.reflect.AccessibleObject
|-java.lang.reflect.Constructor<T>
- 构造方法:无。
- 常用方法:
|
newInstance |
|
|
toString |
三、Field
Java.lang.Object
|-java.lang.reflect.AccessibleObject
|-java.lang.reflect.Field
- 构造方法:无
- 常用方法:
|
getName |
|
|
|
set |
还有诸如getInt与setInt等操作基本数据类型的方法。
四、Method
Java.lang.Object
|-java.lang.reflect.AccessibleObject
|-java.lang.reflect.Method
1.构造方法:无
2.常用方法:
|
|
|
|
|
|
|
|
|
|
|
五、暴力访问
使用方法:Constructor、Field、Method三个类均为AccessibleObject类的子类,AccessibleObject类中有一个方法用于暴力访问类中私有的、受保护的构造方法、成员变量、普通方法。
|
|
|
|
|
|
前者为静态方法,用于为一组对象设置可访问标记的方法,后者为非静态方法,用于为特定的对象设置可访问标记的方法。
六、示例:
package p09.ReflectDemo.p01.Demo01; /**
* @author kuangdaoyizhimei
*
*/
public class Person {
//两个字段
private int age;
private String name;
public String id;
//带参数构造方法
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
System.out.println("Person(int age,String name)run");
}
//无参构造方法
public Person() {
super();
System.out.println("Person()run");
}
//公有无参数show方法
public void show()
{
System.out.println(name+"-----is show runnig---"+age);
}
//私有无参数method方法
private void method()
{
System.out.println("method is running");
}
//私有带参数set方法
private void set(int age,String name)
{
this.age=age;
this.name=name;
System.out.println("set function is run,name is "+name+" ,age is "+age);
}
//公有静态无参数go方法。
public static void go()
{
System.out.println("static go function is running!");
}
}
Person.java
该类封装了一些成员变量和方法。
package p09.ReflectDemo.p01.Demo01; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; /**
* 该类为测试拿到字节码文件中的构造方法。
* @author kuangdaoyizhimei
*
*/
public class GetConstructorDemo { public static void main(String[] args) throws Exception {
getAllConstructors();
getNoneParameterConstructor();
getParameterConstructor();
} /**
* 使用带参数构造方法创建本类实例
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws ClassNotFoundException
*/
private static void getParameterConstructor() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException {
Class<?> clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Constructor<?> con=clazz.getConstructor(int.class,String.class);
Object obj=con.newInstance(24,"张三");
} /**
* 使用无参构造方法创建本类的实例。
* @throws NoSuchMethodException
* @throws SecurityException
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
private static void getNoneParameterConstructor() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Constructor con=clazz.getConstructor();
Object obj=con.newInstance();
} /**
* 得到字节码文件中定义的所有构造方法
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
private static void getAllConstructors() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Constructor arr[]=clazz.getConstructors();
for(Constructor con:arr)
{
System.out.println(con);
}
} }
GetConstructorDemo.java
该类用于演示怎样使用反射机制获取Person.java中的构造方法,并使用获取到的构造方法创建对象(但参数构造方法与不带参数构造方法)。
package p09.ReflectDemo.p01.Demo01; import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* 该类用于拿到字节码文件中的字段。
* @author kuangdaoyizhimei
*
*/
public class GetFieldsDemo {
public static void main(String args[]) throws Exception
{
// getPublicFields();
// getPublicSpecialField();
// getPrivateSpecialField();
}
private static void getPrivateSpecialField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
// Field name=clazz.getField("name");
Field name=clazz.getDeclaredField("name");
name.setAccessible(true);//暴力访问
Object obj=clazz.newInstance();
name.set(obj, "张三");
System.out.println(name.get(obj));
} private static void getPublicSpecialField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Field field=clazz.getField("id");
// System.out.println(field);
Object obj=clazz.newInstance();
field.set(obj, "12345");
System.out.println(field.get(obj));
} private static void getPublicFields() throws ClassNotFoundException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Field f[]=clazz.getDeclaredFields();//得到所有的字段
// Field f[]=clazz.getFields();//得到公有的字段
for(Field field :f)
{
System.out.println(field);
}
}
}
GetFieldsDemo.java
该类用于演示怎样使用反射机制获取Person.java中的字段,并对字段赋值与获取。
package p09.ReflectDemo.p01.Demo01; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; /**
* 该类用于测试拿到字节码文件对象中的普通方法
* @author kuangdaoyizhimei
*
*/
public class GetMethodsDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// showAllMethods();
// getSpecialMethod();
// getSpecialPrivateParameterMethod();
getPublicStaticMethod();
} private static void getPublicStaticMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Method method=clazz.getMethod("go", null);
Object obj=clazz.newInstance();
method.invoke(obj, null);
}
private static void getSpecialPrivateParameterMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Method method=clazz.getDeclaredMethod("set", int.class,String.class);
method.setAccessible(true);//暴力访问,如果不是私有方法,这里可以不使用该语句
Object obj=clazz.newInstance();
method.invoke(obj, 23,"张三");
} private static void getSpecialMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
Method method=clazz.getMethod("show",null);
Object obj=clazz.newInstance();
method.invoke(obj, null);
} private static void showAllMethods() throws ClassNotFoundException {
Class clazz=Class.forName("p09.ReflectDemo.p01.Demo01.Person");
// Method methods[]=clazz.getMethods();//得到所有的公有方法,包括父类的
Method methods[]=clazz.getDeclaredMethods();//得到所有本类中的方法
for(Method method:methods)
{
System.out.println(method);
}
} }
GetMethodsDemo
该类用于演示怎样使用反射机制获取Person.java中的普通方法,并调用特定的方法(带参数方法与不带参数方法)。
七、实例:模拟电脑运行过程
package p10.ReflectDemo.p02.Demo01; /**
* 模拟主板
*
* @author kuangdaoyizhimei
*
*/
public class MainBoard {
public void run() {
System.out.println("主板已经通电,即将运行!");
} public void usePCI(PCI pci) {
if (pci != null) {
pci.open();
pci.close();
}
}
}
MainBoard.java
该类用于模拟主板对象。
package p10.ReflectDemo.p02.Demo01; /**
* 模拟接口PCI
* @author kuangdaoyizhimei
*
*/
public interface PCI {
public void open();
public void close();
}
PCI.java
该接口模拟PCI接口。
package p10.ReflectDemo.p02.Demo01; import java.io.File;
import java.io.FileInputStream;
import java.util.Properties; /**
* 模拟电脑运行
* @author kuangdaoyizhimei
*
*/
public class Entry { public static void main(String[] args) throws Exception {
MainBoard mb=new MainBoard();
mb.run(); //这种扩展方法烂透了,应当使用反射技术来完成,可以大大提高扩展性
// mb.usePCI(new SoundCard()); File file=new File("pci.conf");
FileInputStream fis=new FileInputStream(file);
Properties pro=new Properties();
pro.load(fis);
if(pro.size()>=4)
for(int i=0;i<4;i++)
{
String pciname=pro.getProperty("pci"+(i+1));
if(pciname.equals(""))
continue;
Class<?> clazz=Class.forName(pciname);
PCI pci=(PCI)clazz.newInstance();
mb.usePCI(pci);
}
fis.close();
}
}
Entry.java
该类模拟电脑运行过程。
pci1=p10.ReflectDemo.p02.Demo01.SoundCard
pci2=
pci3=
pci4=
pci.conf
该配置文件用于模拟给主板插上扩展硬件,如声卡、显卡等,默认有声卡
运行结果为:

如果想要添加一个显卡,则只需要改变配置文件为:
pci1=p10.ReflectDemo.p02.Demo01.SoundCard
pci2=p10.ReflectDemo.p02.Demo01.DisplayCard
pci3=
pci4=
pci.conf
同时需要在p10.ReflectDemo.p02.Demo01包下创建DisplayCard.java文件,该类实现了PCI接口。
package p10.ReflectDemo.p02.Demo01;
public class DisplayCard implements PCI {
@Override
public void open() {
System.out.println("显卡已经打开!");
}
@Override
public void close() {
System.out.println("显卡已经关闭!");
}
}
DisplayCard.java
这样,就可以将该显卡安装到了主板上,电脑运行时就可以正常使用该显卡了。
运行结果是:

八、总结。
接口+配置文件是软件开发中非常有用的开发方式,使用这种开发范式可以极大扩展软件功能而不需要修改源代码。
【JAVA反射机制】的更多相关文章
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- Java反射机制专题
·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- Java反射机制DOME
Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...
- 反射——Java反射机制
反射概述 什么是反射? ① 反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ② JAVA反射机制是在运行状态中,对应任意一个类,都能 ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
- Java反射机制学习与研究
Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...
随机推荐
- IC/RFID/NFC 关系与区别
IC卡 (Integrated Circuit Card,集成电路卡) 有些国家和地区也称智能卡(smart card).智慧卡(intelligent card).微电路卡(microcircuit ...
- mysql 主从数据库设置方法
1.主从数据库都需开启bin-log日志 2.在my.ini(windows)或my.cnf(linux)配置文件中添加 server-id = 1(主从配置 id 必须不同) 例子: [mysqld ...
- Kali Linux渗透基础知识整理(四):维持访问
Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...
- 数据统计表插件,highcharts插件的简单应用
highcharts插件的简单应用,非常全能好用的一个数据统计表插件. $(function () { $('#container').highcharts({ chart:{ type:" ...
- zabbix之php安装
转载自: http://www.ttlsa.com/nginx/nginx-php-5_5/ php下载 https://pan.baidu.com/s/1qYGo8bE
- linux下的shell运算(加、减、乘、除)
linux下的shell运算(加.减.乘.除) 标签: linuxshell运算加减乘除 2014-03-12 16:25 15127人阅读 评论(0) 收藏 举报 分类: linux(17) ((i ...
- 一个简单的任务执行时间监视器 StopWatch
有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观, 如果想对执行的时间做进一步 ...
- 【Unity3D】Invoke,InvokeRepeating ,Coroutine 延迟调用,周期性调用
Invoke和InvokeRepeating方法,可以实现延迟调用,和周期调用 第一个是执行一次,第二个是重复执行 void Invoke(string methodName, float time) ...
- mysql性能优化学习笔记-参数介绍及优化建议
MySQL服务器参数介绍 mysql参数介绍(客户端中执行),尽量只修改session级别的参数. 全局参数(新连接的session才会生效,原有已经连接的session不生效) set global ...
- php xdebug配置
2015年11月27日 17:08:54 [xdebug] ;用触发的形式去开启跟踪调试 get/post/cookie 中添加变量"XDEBUG_TRACE" xdebug.au ...