一、Class类

Java.lang.Object

|-java.lang.Class<T>

构造方法:无。

常用方法:

static Class<?>

forName(String className)
          返回与带有给定字符串名的类或接口相关联的
Class 对象。

Constructor<T>

getConstructor(Class<?>... parameterTypes)
          
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。

Constructor<?>[]

getConstructors()
          
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

 Constructor<T>

getDeclaredConstructor(Class<?>... parameterTypes)
          
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。

 Constructor<?>[]

getDeclaredConstructors()
          
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。

 Field

getDeclaredField(String name)
          
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

 Field[]

getDeclaredFields()
          
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

 Method

getDeclaredMethod(String name, Class<?>... parameterTypes)
          
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。

 Method[]

getDeclaredMethods()
          
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

 Field

getField(String name)
          
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

 Field[]

getFields()
          
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。

 Method

getMethod(String name, Class<?>... parameterTypes)
          
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。

 Method[]

getMethods()
          
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共
member 方法。

 T

newInstance()
          
创建此 Class 对象所表示的类的一个新实例。

二、Constructor

Java.lang.Object

|-java.lang.reflect.AccessibleObject

|-java.lang.reflect.Constructor<T>

  1. 构造方法:无。
  2. 常用方法:

 T

newInstance(Object... initargs)
          使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

 String

toString()
          
返回描述此 Constructor 的字符串。

三、Field

Java.lang.Object

|-java.lang.reflect.AccessibleObject

|-java.lang.reflect.Field

  1. 构造方法:无
  2. 常用方法:

 Object

get(Object obj)
          返回指定对象上此
Field 表示的字段的值。

 String

getName()
          
返回此 Field 对象表示的字段的名称。

 void

set(Object obj, Object value)
          
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

还有诸如getInt与setInt等操作基本数据类型的方法。

四、Method

Java.lang.Object

|-java.lang.reflect.AccessibleObject

|-java.lang.reflect.Method

1.构造方法:无

2.常用方法:

 String

getName()
          以 String 形式返回此 Method 对象表示的方法名称。

 Class<?>

getReturnType()
          
返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。

 Object

invoke(Object obj, Object... args)
          
对带有指定参数的指定对象调用由此
Method 对象表示的底层方法。

 String

toString()
          
返回描述此 Method 的字符串。

五、暴力访问

使用方法:Constructor、Field、Method三个类均为AccessibleObject类的子类,AccessibleObject类中有一个方法用于暴力访问类中私有的、受保护的构造方法、成员变量、普通方法。

static void

setAccessible(AccessibleObject[] array,
boolean flag)

          使用单一安全性检查(为了提高效率)为一组对象设置
accessible 标志的便捷方法。

 void

setAccessible(boolean flag)
          
将此对象的 accessible 标志设置为指示的布尔值。

前者为静态方法,用于为一组对象设置可访问标记的方法,后者为非静态方法,用于为特定的对象设置可访问标记的方法。

六、示例:

 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反射机制】的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  4. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  5. Java反射机制专题

    ·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...

  6. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  7. Java反射机制DOME

    Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...

  8. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  10. Java反射机制学习与研究

    Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...

随机推荐

  1. How to tile small texture image onto page as its background

    You don’t need to set a big size image as the background of pages if the image is texture or uniform ...

  2. C# XML和实体类之间相互转换(序列化和反序列化)

    我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. using System; using System.Collections.Ge ...

  3. xargs命令

    xargs命令 常用工具命令 xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具.它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令 ...

  4. java导出生成word

    最近做的项目,需要将一些信息导出到word中.在网上找了好多解决方案,现在将这几天的总结分享一下. 目前来看,java导出word大致有6种解决方案: 1:Jacob是Java-COM Bridge的 ...

  5. Sharepoint2013 中想要将网站另存为模板步骤

    Sharepoint2013 中想要将网站另存为模板步骤 第一步:使用SPD打开想要另存为模板的网站,找到网站选项: 第二步:点击打开网站选项,找到一个SaveSiteAsTemplateEnable ...

  6. 不知道数据库中表的列类型的前提下,使用JDBC正确的取出数据

    概要: 使用jdbc 如果在不知道表结构的情况下,如何读出表信息? 使用ResultSetMetaData; 然后使用getColumnType 获取column 类型 使用getColumnName ...

  7. ACM/ICPC 之 拓扑排序范例(POJ1094-POJ2585)

    两道拓扑排序问题的范例,用拓扑排序解决的实质是一个单向关系问题 POJ1094(ZOJ1060)-Sortng It All Out 题意简单,但需要考虑的地方很多,因此很容易将code写繁琐了,会给 ...

  8. 21. javacript高级程序设计-Ajax与Comet

    1. Ajax与Comet 1.1 XMLHttpRequest对象 IE5是第一款引入XHR对象的浏览器,IE5中是通过MSXML库中的一个ActiveX对象实现的.因此在IE中可能存在MSXML2 ...

  9. c语言实现面向对象OOC

    这种问题比较锻炼思维,同时考察c和c++的掌握程度.如果你遇到过类似问题,此题意义自不必说.如果用c实现c++,主要解决如何实现封装,继承和多态三大问题,本文分两块说. 1.封装 // Example ...

  10. CString之GetBuffer与ReleaseBuffer

    我们知道,CString是MFC中提供的方便字符串操作的一个类,非常好使,具有自动动态内存管理功能. GetBuffer()主要作用是将字符串的缓冲区长度锁定: ReleaseBuffer()则是解除 ...