一、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. STM32通用定时器(转载)

    STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...

  2. explicit,violate,volatile,mutable小结

    转自:http://blog.csdn.net/helonsy/article/details/7091130 explicit:放在构造函数前面可以阻止构造函数的隐式类型转换.这样可以避免不必要的错 ...

  3. js清空array数组的方法

    方式1,splice Js代码   ,,,}; ary.length = ; Java中会报错,编译通不过. 而JS中则可以,且将数组清空了,如 Js代码   var ary = [1,2,3,4]; ...

  4. 无法解析类型 javax.servlet.http.HttpServletRequest。从必需的 .class 文件间接引用

    java.lang.Error: 无法解析的编译问题: 无法解析类型 javax.servlet.http.HttpServletRequest.从必需的 .class 文件间接引用了它 无法解析类型 ...

  5. httpclient+Jsoup总结

    Jsoup.parse解析HTML字符串,如Jsoup.parse("<html><head><title>Firstparse</title> ...

  6. php 通过API接口连接12306余票查询

    <?php header("content-type:text/html;charset='utf-8'"); //设置编码 echo "<meta cont ...

  7. 【架构】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 ...

  8. HTML——meta标签

    <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. <meta> 标签位于文档的头部,不包含任何内容.&l ...

  9. PDF.js

    http://www.linuxidc.com/Linux/2015-06/118728.htm http://blog.csdn.net/xiangcns/article/details/42089 ...

  10. VMware Workstation 下进行 桥连接

    大家都知道进行桥连接的时候,需要我们的宿主机与虚拟机同处于一个网络段, 使得mask与默认网关相同即可进行连接 ; 本地的IP .掩码 . 网关: 虚拟机的Ip 掩码,网关: // 当然这里的DNS ...