`
liqita
  • 浏览: 287442 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA 反射详细讲解 实例

阅读更多

  一、反射的含义:

Java类的一种自审机制,它是一种可以认识自身和动态改变自身的一种行为。

二、反射的使用:

1、通常在对文件操作时需要用到类的反射机制,通过反射可以获取一个未知类的内部信息(如:属性、方法等)

2、本使用步骤:

A、反射应用中首先应用Class创建一个指向某个类(如A类,非默认包时应加上包名)的对象。

B、利用刚创建的对象调用getDeclaredField/getDeclaredFields获取A类中的指定属性或所有属性(返回Field数 组);调用 getDeclaredMethod/getDeclaredMethods获取A类中的指定方法或所有方法(返回Method数组);调用 getDeclaredConstructor/getDeclaredConstructors获取A类中指定构造方法或所有构造方法(返回 Constructor数组)。

C、上述2步过程若不加Declared则指定调用公共的属性及方法

D、上述2步过程在操作非共有(尤其为私有情况时)属性及方法时应用反射方法对象或反射属性对象调用setAccessible(true)去除java系统的调用访问检查。

 

在开始之前,我先定义一个测试类Student,代码如下:
 1 package chb.test.reflect;  
 2  
 3  public class Student {  
 4     private int age;  
 5     private String name;  
 6     public int getAge() {  
 7         return age;  
 8      }  
 9     public void setAge(int age) {  
10         this.age = age;  
11      }  
12     public String getName() {  
13         return name;  
14      }  
15     public void setName(String name) {  
16         this.name = name;  
17      }  
18       
19     public static void hi(int age,String name){  
20          System.out.println("大家好,我叫"+name+",今年"+age+"岁");  
21      }  
22 }
一、JAVA反射的常规使用步骤
反射调用一般分为3个步骤:
·得到要调用类的class
·得到要调用的类中的方法(Method)
·方法调用(invoke)
代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});  
3 m.invoke(cls.newInstance(),20,"chb");
二、方法调用中的参数类型
在方法调用中,参数类型必须正确,这里需要注意的是不能使用包装类替换基本类型,比如不能使用Integer.class代替int.class。
如我要调用Student的setAge方法,下面的调用是正确的
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Method setMethod = cls.getDeclaredMethod("setAge",int.class);  
3 setMethod.invoke(cls.newInstance(), 15);
  而如果我们用Integer.class替代int.class就会出错,如:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);  
3 setMethod.invoke(cls.newInstance(), 15);
jvm会报出如下异常:
1 java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)  
2 at java.lang.Class.getDeclaredMethod(Unknown Source)
3 at chb.test.reflect.TestClass.testReflect(TestClass.java:23)
三、static方法的反射调用
static方法调用时,不必得到对象示例,如下:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);  
3 staticMethod.invoke(cls,20,"chb");//这里不需要newInstance  
4 //staticMethod.invoke(cls.newInstance(),20,"chb");
四、private的成员变量赋值
如果直接通过反射给类的private成员变量赋值,是不允许的,这时我们可以通过setAccessible方法解决。代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Object student = cls.newInstance();//得到一个实例  
3 Field field = cls.getDeclaredField("age");  
4 field.set(student, 10);  
5 System.out.println(field.get(student));
运行如上代码,系统会报出如下异常:
1 java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"  
2      at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)  
3      at java.lang.reflect.Field.doSecurityCheck(Unknown Source)  
4      at java.lang.reflect.Field.getFieldAccessor(Unknown Source)  
5      at java.lang.reflect.Field.set(Unknown Source)  
6      at chb.test.reflect.TestClass.testReflect(TestClass.java:20)
解决方法:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Object student = cls.newInstance();  
3 Field field = cls.getDeclaredField("age");  
4 field.setAccessible(true);//设置允许访问  
5 field.set(student, 10);  
6 System.out.println(field.get(student));
其实,在某些场合下(类中有get,set方法),可以先反射调用set方法,再反射调用get方法达到如上效果,代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");  
2 Object student = cls.newInstance();  
3  
4 Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);  
5 setMethod.invoke(student, 15);//调用set方法  
6               
7 Method getMethod = cls.getDeclaredMethod("getAge");  
8 System.out.println(getMethod.invoke(student));//再调用get方法

分享到:
评论
3 楼 liqita 2012-08-28  
谢谢 
2 楼 donghaiwang 2012-08-17  
1 楼 donghaiwang 2012-08-17  

相关推荐

    Java反射机制的详细讲解及实例,有助于java深度开发

    本文档对Java中使用最广的反射进行了深度而让人简单容易理解的解析,附有实例,可供致力于java底层研究的人提供借鉴

    Java反射实例源码

    Java反射实例源码,具体讲解内容见博客http://blog.csdn.net/liushuijinger 菜鸟学编程(九)——Java反射机制(一) 菜鸟学编程(十)——Java反射机制(二)

    实例讲解java的反射

    实例讲解java的反射 实例讲解java的反射

    JAVA反射机制实例详解

    主要介绍了JAVA反射机制,以实例形式较为详细的分析讲解了Java反射机制的具体概念、功能与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    java反射机制.rar

    1简单反射机制实例 2各各方法以及类的应用实例 3代理模式 内有详细讲解说明保证大家理解并会应用反射

    Java 反射机制原理与用法详解

    主要介绍了Java 反射机制原理与用法,结合实例形式详细分析了Java反射机制的相关概念、原理、基本使用方法及操作注意事项,需要的朋友可以参考下

    动力节点_Java基础视频教程163_反射创建实例

    动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...

    实例讲解Java基础之反射

    今天小编就为大家分享一篇关于实例讲解Java基础之反射,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java范例大全 源码

    其次,《Java范例大全》还讲解了XML开发、Java图形编程、Java网络编程、多媒体开发、邮件开发、Java Web开发和Java安全等大量极其重要的企业级开发知识,使全书上升到一个新的高度;最后,以一个极具代表性的综合...

    Java开发详解.zip

    031504_【第15章:Java反射机制】_Java反射机制的深入研究笔记.pdf 031505_【第15章:Java反射机制】_动态代理笔记.pdf 031506_【第15章:Java反射机制】_工厂设计模式笔记.pdf 031601_【第16章:Annotation】_系统...

    实例讲解Java编程中数组反射的使用方法

    主要介绍了Java编程中数组反射的使用方法,通过编写数组反射工具类可以重用许多基础代码,减少对类型的判断过程,需要的朋友可以参考下

    Java SE编程入门教程 java集合(共38页).pptx

    Java SE编程入门教程 java反射机制(共16页).pptx Java SE编程入门教程 java泛型(共11页).pptx Java SE编程入门教程 java封装继承多态(共56页).pptx Java SE编程入门教程 java集合(共38页).pptx Java SE编程...

    Java反射机制(Reflection)浅析

    主要介绍了Java反射机制(Reflection)浅析,本文以实例讲解Java的反射机制,需要的朋友可以参考下

    Java常见面试题.pdf

    14. 解释 Java 中的反射机制。 15. 如何连接和操作数据库(如 MySQL)? 16. 什么是 JVM(Java 虚拟机)?它的作用是什么? 17. 解释 Java 中的垃圾回收(Garbage Collection)机制。 18. 什么是设计模式?列举几个...

    java-learning:逐步打造在线最佳的Java学习笔记,包括博客讲解和源码实例,包括Java SE和Java Web

    含博客讲解和二进制实例,采用maven构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个star吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要...

    JavaRpc:JAVA RPC实现,基于动态代理与反射

    RPC Java实例讲解 废话不多说,现在讲讲RPC到底是什么 RPC基本原理 RPC全程Remote Procedure Call Protocol,即远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。...

    Kotlin中的反射机制深入讲解

    这一特性使得反射机制被常常用在框架中,想要比较系统的了解Kotlin中的反射,先从Java的反射说起。 Java中的反射 通常我们写好的.java源码文件,经过javac的编译,最终生成了.class字节码文件。这些字节码文件是与...

    Java2核心技术.part5

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝...

    Java 高级特性.doc

    2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。 3、泛型的类型参数可以有多个。 4、泛型的参数类型可以使用extends语句,例如。习惯上成为“有界类型”。 5、泛型的...

Global site tag (gtag.js) - Google Analytics