【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 ...
随机推荐
- STM32通用定时器(转载)
STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...
- explicit,violate,volatile,mutable小结
转自:http://blog.csdn.net/helonsy/article/details/7091130 explicit:放在构造函数前面可以阻止构造函数的隐式类型转换.这样可以避免不必要的错 ...
- js清空array数组的方法
方式1,splice Js代码 ,,,}; ary.length = ; Java中会报错,编译通不过. 而JS中则可以,且将数组清空了,如 Js代码 var ary = [1,2,3,4]; ...
- 无法解析类型 javax.servlet.http.HttpServletRequest。从必需的 .class 文件间接引用
java.lang.Error: 无法解析的编译问题: 无法解析类型 javax.servlet.http.HttpServletRequest.从必需的 .class 文件间接引用了它 无法解析类型 ...
- httpclient+Jsoup总结
Jsoup.parse解析HTML字符串,如Jsoup.parse("<html><head><title>Firstparse</title> ...
- php 通过API接口连接12306余票查询
<?php header("content-type:text/html;charset='utf-8'"); //设置编码 echo "<meta cont ...
- 【架构】How To Use HAProxy to Set Up MySQL Load Balancing
How To Use HAProxy to Set Up MySQL Load Balancing Dec 2, 2013 MySQL, Scaling, Server Optimization U ...
- HTML——meta标签
<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. <meta> 标签位于文档的头部,不包含任何内容.&l ...
- PDF.js
http://www.linuxidc.com/Linux/2015-06/118728.htm http://blog.csdn.net/xiangcns/article/details/42089 ...
- VMware Workstation 下进行 桥连接
大家都知道进行桥连接的时候,需要我们的宿主机与虚拟机同处于一个网络段, 使得mask与默认网关相同即可进行连接 ; 本地的IP .掩码 . 网关: 虚拟机的Ip 掩码,网关: // 当然这里的DNS ...