什么是反射?反射就是将字节码中的各种成分映射到相应的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. add to svn ignore disabled

    The problem is that the folder is already under version control. Here's how I fix this type of probl ...

  2. 部署 mozilla-BrowserQuest

    1,到GitHub下载代码  https://github.com/mozilla/BrowserQuest 2,安装Node.Js 下载地址 http://nodejs.org/ 直接下载安装版就可 ...

  3. Visual Studio 不生成.vshost.exe和.pdb文件的方法

    使用Visual Studio编译工程时,默认设置下,即使选择了「Release」时也会生成扩展名为「.vshost.exe」和「.pdb」的文件. 一.先解释一下各个文件的作用: .pdb文件: 程 ...

  4. Bootstrap 3兼容IE8浏览器(转)

    Bootstrap是一个响应式的布局,你可以在宽屏电脑.普通电脑,平板电脑,手机上都得到非常优秀的布局体验.这种响应式的布局正是通过CSS3的媒体查询(Media Query)功能实现的,根据不同的分 ...

  5. .net平台的RSA实现以及与Delphi之间的互操作性

    .net平台下面的RSA算法实现是RSACryptoServiceProvider,如果安装了 Microsoft Enhanced Cryptographic Provider,则 RSACrypt ...

  6. HackerRank "Permutation game"

    A typical game theory problem - Recursion + Memorized Searchhttp://justprogrammng.blogspot.com/2012/ ...

  7. Python基础教程【读书笔记】 - 2016/7/24

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第九波:第9章  魔法方法.属性和迭代器  在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.已 ...

  8. Redis容灾部署(哨兵Sentinel)

    Redis容灾部署(哨兵Sentinel) 哨兵的作用 1. 监控:监控主从是否正常2. 通知:出现问题时,可以通知相关人员3. 故障迁移:自动主从切换4. 统一的配置管理:连接者询问sentinel ...

  9. activiti自定义流程之整合(二):使用angular js整合ueditor创建表单

    注:整体环境搭建:activiti自定义流程之整合(一):整体环境配置 基础环境搭建完毕,接下来就该正式着手代码编写了,在说代码之前,我觉得有必要先说明一下activit自定义流程的操作. 抛开自定义 ...

  10. web开发

    教程 html教程 CSS 教程 JavaScript 教程 参考手册 HTML 4.01 / XHTML 1.0 参考手册 CSS 参考手册 JavaScript 参考手册 PHP 手册 CodeI ...