【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 ...
 
随机推荐
- SPOJ 375 Query on a tree
			
Description 给出一个树,每条边有边权,支持两种操作,询问 \(u,v\) 路径上边权最大值,修改第 \(i\) 条边的边权,\(n\leqslant 10^4,T\leqslant 10\ ...
 - 10 DelayQueue 延时队列类——Live555源码阅读(一)基本组件类
			
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 www.cnblogs.com/oloroso/ 本文由乌合 ...
 - ModelAndView的介绍
			
ModelAndView的构造方法有7个.但是它们都是相通的.这里使用无参构造函数来举例说明如何构造ModelAndView实例. ModelAndView类别就如其名称所示,是代表了MVC Web程 ...
 - sone2(未完成)
			
先留个半完成代码 边看论文边看题解写的...难受.. #include<cstdio> #include<cstring> namespace utils{ inline in ...
 - oracle 存储过程中调用存储过程
			
create procedure sp_name() begin ……… end 比如: create procedure pro_showdbs() show datebase; end //用ex ...
 - ASP.NET 上的 Async/Await 简介
			
原文链接 大多数有关 async/await 的在线资源假定您正在开发客户端应用程序,但在服务器上有 async 的位置吗?可以非常肯定地回答“有”.本文是对 ASP.NET 上异步请求的概念性概述, ...
 - .net MVC借助Iframe实现无刷新上传文件
			
html: <div id="uploadwindow" style="display: none;"> <form action=" ...
 - centos 7 升级后yum install出现Exiting on user cancel
			
centos 7 升级后yum install出现Exiting on user cancel centos 7.x升级后用yum install进行安装时经常出现Exiting on user ca ...
 - rabbitMQ中vhost虚拟主机的理解
			
每个virtual host本质上都是一个RabbitMQ Server,拥有它自己的queue,exchagne,和bings rule等等.这保证了你可以在多个不同的application中使用R ...
 - BM算法和Sunday快速字符串匹配算法
			
BM算法研究了很久了,说实话BM算法的资料还是比较少的,之前找了个资料看了,还是觉得有点生涩难懂,找了篇更好的和算法更好的,总算是把BM算法搞懂了. 1977年,Robert S.Boyer和J St ...