什么是反射?反射就是将字节码中的各种成分映射到相应的java类中来,java反射技术自JDK1.1以来就出现了,目前大多数流行的框架都采用了这种技术,可见其重要性,这篇文章将详细介绍我对java反射技术的一些研究.

代表字节码对象的Class

java中所有的类都有自己特有的一份字节码,当程序调用该类时,JVM便会将这份字节码装载到内存中来。在java中主要有三种方法来得到相应的字节码对象。

  1. 通过类的实例的getClass()方法获取,如 Class clazz=new Date().getClass()得到了Date类的字节码对象。
  2. 通过类的class属性获取。如Class clazz=String.class或者Class clazz=System.class.值得注意的是,java中八个主类型 (byte,char,short,int,long,float,double,boolean)和一个返回类型void都有class属性,并且都返 回自己的字节码对象。如int.class,boolean.class,float.class等。其中他们的包装类的TYPE属性也分别返回它们主类 型的那份字节码,如int.class==Integer.TYPE为true,void.class==Void.TYPE为true;
  3. 通过Class类的forName()方法获取,如Class clazz=Class.forName("java.lang.Math");

java中可以通过Class类的isPrimitive()方法判断当前的字节码是否为主类型,isEnum()判断字节码是否为枚举类。 isArray()判断字节码是否为数组类型。某个类和它所组成的数组分别持有的字节码也不相同,例如int.class==int[].class这种 写法在编译期就会被编译器阻止,因为编译器发现两边参与比较的对象不在一个继承树分支上。只有相同类型和相同维度的数组才会共用一个字节码对象,如int a1[]=new int[1], a2[]=new int[5];int a3[][]=new int[2][5];a1.getClass()==a2.getClass()为true,a2.getClass()==a3.getClass() 为false;

代表构建器的Constructor

java中用getConstructor()和getConstructors()方法返回某一个public的构建器和所有public访问级 别的构建器,而getDeclaredConstructor()和getDeclaredConstructors()返回所有构建器中的某一个构建器 和所有的构建器。Constructor可以通过newInstance()方法创建一个该类的实例。如下例所示

Class clazz=String.class;

Constructor cs=clazz.getConstructor(StringBuffer.class);

String s=(String)cs.newInstance(new StringBuffer("abc"));

上面的代码相当于

String s=new String(new StringBuffer("abc"));

又如下例所示

String obj=String.class.getConstructor().newInstance();

上面的代码相当于

String obj=new String();

如果要得到所有的构建器可以按下面的方法做。

Constructor[] allCons=String.class.getDeclaredConstructors();

for(Construcotr con:allCons)

System.out.println(con.getName());

除了Constructor类中提供了newInstance()方法,Class类中也有一个类似的newInstance()方法,因为我们可以直接在得到字节码对象时便可生成该字节码的对象了。

ArrayList al=(ArrayList)ArrayList.class.newInstance();事实上得到构建器对象的那一步已经被封装在Class的newInstance()方法中。

public Object newInstance()

{

this.getConstructor().newInstance();

}

代表字段的Field

Class类中提供了getField()和getFields()得到public级别的字段中的某一个和所有public级别的字段,getDeclaredField()和getDeclaredFields()得到所有字段中的某一个和所有的字段。

如果某个字段是数组类型的,那么要对它进行反射还需要借助java.lang.reflect.Array来进行操作。有些时候得到的字段为 private访问级别的,如果这个时候想要读取和设值该字段一般情况下会报运行期异常,但是java反射技术也并不是对此无能为力,运用反射可以绕过编 译器的某些限制,来进行“暴力反射”。此时只需设置Field的setAccessible()为true就可以了。

代表成员方法的Method

Class类中同样提供了getMethod(),getMethods()用来得到得到public级别的方法和所有public的方法,以及 getDeclaredMethod()和getDeclaredMethods()方法用来得到任何访问级别的某一个方法和所有任何访问级别的方法.

对内部类的反射

网上的资料对于如何运用反射将内部类映射出来的资料非常之少,为此我特意花了一个多小时研究了一会儿,下面把研究的结果写到下面。

Class类本身还提供对于获取内部类字节码的方法,分别为getClasses和getDeclaredClasses(),其中 getClasses()只能得到访问级别为public的内部类,而getDeclaredClasses()则能得到所有声明了的内部类。

由于内部类可以分为实例内部类,静态内部类,匿名内部类,前面提到的getClasses()和getDeclaredClasses()目前还都 只能得到实例内部类和静态内部类,对于后面两种情况却无能为力,为此还需要采取一些特殊的手段才能针对匿名内部类进行反射操作。

package net.csdn.blog;
public class ReflectInnerClass { public Runnable ta=new Runnable(){
public void run(){
System.out.println("匿名内部类中的方法被执行了");
}
}; private class Inner2{
public Inner2(){
System.out.println("Inner2类被实例化了");
}
} class Inner3{
public Inner3(){
System.out.println("Inner2类被实例化了");
}
}
public class Inner1{
public Inner1(){
System.out.println("Inner1类被实例化了");
}
}
}

下面对内部类进行反射

java 反射技术的更多相关文章

  1. Android中Java反射技术的使用示例

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  2. java反射技术实例

    java反射技术实例​1. [代码][Java]代码     package com.gufengxiachen.java.reflectiontest; public class Person {p ...

  3. Android 插件化开发(一):Java 反射技术介绍

    写在前面:学习插件化开发推荐书籍<Android 插件化开发指南>,本系列博客所整理知识部分内容出自此书. 在之前的项目架构的博文中,我们提到了项目插件化架构,提到插件化架构不得不提的到J ...

  4. java反射技术主要实现类有哪些,作用分别是什么

    Java反射技术主要实现类有哪些,作用分别是什么? 在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中 1)Class类:代表一个类 2)Field 类 ...

  5. Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框

    原文出处:博主宇宙的极客http://www.cnblogs.com/nokiaguy/archive/2010/07/27/1786482.html 众所周知,AlertDialog类用于显示对话框 ...

  6. 由浅入深理解----java反射技术

    java反射机制详解 java反射机制是在运行状态下,对任意一个类可以获取该类的属性和方法,对任意一个对象可以调用其属性和方法.这种动态的获取信息和调用对象的方法的功能称为java的反射机制 clas ...

  7. 使用JAVA反射技术实现代码零耦合与功能无限扩展!

    1.反射使用的背景 最近在做一个功能,就是实现邮件发送功能,但是邮件发送有不同的内容和数据格式,在开始设计的时候直接将发送的内容写在了发送模块中,后来发现功能增加后,无法继续在里边写了,因为里边的功能 ...

  8. JAVA反射技术的使用

    前言 在开发html使用jquery提交post的时候,可以使用jquery遍历from元素里面的input元素实现参数组合,这样就不用手动打参数了,特别是在参数很多的时候,费神费时. 我开发Andr ...

  9. java反射技术详解

    反射: 其实就是动态的从内存加载一个指定的类,并获取该类中的所有的内容. 反射的好处:大大的增强了程序的扩展性. 反射的基本步骤: 1. 获得Class对象,就是获取到指定的名称的字节码文件对象. 2 ...

随机推荐

  1. PHP 5.6.11 访问SQL Server2008R2

    PHP天生支持MySQL,但是有时候也想让它访问SQL Server,该怎么办呢? 最近找了点资料,测试成功了PHP访问SQLSvr的几种情况,限于时间,还没有测试更多不同环境,把测试过的记录如下: ...

  2. 高效能团队协作的JIRA实践

    http://www.csdn.net/article/2015-05-21/2824739?utm_source=tuicool 高效能团队是企业生存和发展的基石.任何企业面对当下的激烈竞争,要想脱 ...

  3. 阿里云nat mysql配置

    # Generated by iptables-save v1. :: *filter :INPUT DROP [:] :FORWARD ACCEPT [:] :OUTPUT ACCEPT [:] # ...

  4. java 常用集合例子

    package test; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import ...

  5. C语言常用的小代码

    圆周率Pi tan(Pi/4)=1 => Pi=4*arctan(1) 反正切函数arctan()在C语言里表示为atan(),为保证精度取圆周率的代码如下: const double Pi = ...

  6. mysql 获取一个表中缺失的最小编号

    select count(*),t1.`name` from test_id t1INNER JOIN test_id t2on t1.id >= t2.idgroup by t1.id,t1. ...

  7. WSUS目录本地迁移

    生产环境中有一台win2003 server,安装了Microsoft Windows Server Update Services 3.0,作为所有windows server的内网补丁更新服务器, ...

  8. Learning Puppet — Resource Ordering

    Learning Puppet — Resource Ordering Learn about dependencies and refresh events, manage the relation ...

  9. TextBox(只允许输入字母或者数字)

    实现如下: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System ...

  10. oracle学习笔记(一)配置监听

    服务器端: 监听器   lsnrctl 启动监听 lsnrctl start [LISTENER] 查看监听 lsnrctl  status  或者  lsnrctl  service C:\Docu ...