三个主要的反射类


  Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法类等元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。这些反射对象类在java.reflect包中定义,下面是最主要的三个反射类:

  • Constructor:类的构造函数反射类,通过Class#getConstructors()方法可以获得类的所有构造函数反射对象数组。在JDK5.0中,还可以通过getConstructor(Class... parameterTypes)获取拥有特定入参的构造函数反射对象。Constructor的一个主要方法是newInstance(Object[] initargs),通过该方法可以创建一个对象类的实例,相当于new关键字。在JDK5.0中该方法演化为更为灵活的形式:newInstance(Object... initargs)。
  • Method:类方法的反射类,通过Class#getDeclaredMethods()方法可以获取类的所有方法反射类对象数组Method[]。在JDK5.0中可以通过getDeclaredMethod(String name, Class... parameterTypes)获取特定签名的方法,name为方法名;Class...为方法入参类型列表。Method最主要的方法是invoke(Object obj, Object[] args),obj表示操作的目标对象;args为方法入参,下面代码清单中3.处演示了这个反射类的使用方法。在JDK5.0中,该方法的形式调整为invoke(Object obj, Object... args)。此外,Method还有很多用于获取类方法更多信息的方法:
    1. Class getReturnType():获取方法的返回值类型;
    2. Class[] getParameterTypes():获取方法的入参类型数组;
    3. Class[] getExceptionTypes():获取方法的异常类型数组;
    4. Annotation[][] getParameterAnnotations():获取方法的注解信息,JDK5.0中的新方法;
  • Field:类的成员变量的反射类,通过Class#getDeclaredFields()方法可以获取类的成员变量反射对象数组,通过Class#getDeclaredField(String name)则可获取某个特定名称的成员变量反射对象。Field类最主要的方法是set(Object obj, Object value),obj表示操作的目标对象,通过value为目标对象的成员变量设置值。如果成员变量为基础类型,用户可以使用Field类中提供的带类型名的值设置方法,如setBoolean(Object obj, boolean value)、setInt(Object obj, int value)等。
  • 除此之外,Java还为包提供了Package反射类,在JDK5.0中还为注解提供了AnnotatedElement反射类。
 /**
* Copyright 2016 Zhengbin's Studio.
* All right reserved.
* 2016年7月1日 下午2:24:19
*/
package Nine; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; /**
* @author zhengbinMac
*
*/
public class ReflectTest { public static Car initByDefaultConst() throws ClassNotFoundException,... {
// 1.通过类装载器获取Car类对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// Class clazz = loader.loadClass("Nine.Car");
Class clazz = Class.forName("Nine.Car");
// 2.获取类的默认构造器对象并通过它实例化Car
Constructor cons = clazz.getDeclaredConstructor((Class[])null);
Car car = (Car)cons.newInstance(); car.introduce(); // 3.通过反射方法设置属性
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car, "BMW");
Method setColor = clazz.getMethod("setColor", String.class);
setColor.invoke(car, "red");
Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car, 280); // 4.通过反射方法设置类的成员变量
Field fild = clazz.getDeclaredField("NUM");
fild.set(car, 2); // car.setBrand("BMW");
// car.setColor("red");
// car.setMaxSpeed(280);
return car;
} public static void main(String[] args) throws ClassNotFoundException,... {
Car car = initByDefaultConst();
car.introduce();
System.out.println(car.getNUM());
}
}

  总之,Java的反射体系保证了可以通过程序化的方式访问目标类中所有的元素,对于private或protected的成员变量和方法,只要JVM的安全机制允许,也可以通过反射进行调用。

对于private或protected的成员变量的和方法的反射调用


  通过下面代码说明这个问题:

 /**
* @author zhengbinMac
*/
public class PrivateCar {
private String color;
protected void drive() {
System.out.println("drive private car! the color is:" + color);
}
}
 /**
* @author zhengbinMac
*/
public class PrivateCarReflect {
public static void main(String[] args) throws ClassNotFoundException,... {
Class clazz = Class.forName("Nine.PrivateCar");
PrivateCar car = (PrivateCar)clazz.newInstance();
Field field = clazz.getDeclaredField("color");
// 1.取消Java语言访问检查以访问private变量
field.setAccessible(true);
field.set(car, "红色");
Method driveMtd = clazz.getDeclaredMethod("drive",(Class[])null);
// 2.取消Java语言访问检查以访问protected方法
driveMtd.setAccessible(true);
driveMtd.invoke(car, (Object[])null);
}
}

  将输出:drive private car! the color is:红色

  在访问private、protected成员变量和方法时必须通过setAccessible(boolean access)方法取消Java语言检查,否则将抛出IllegalAccessException。如果JVM的安全管理器设置了相应的安全机制,调用该方法将抛出SecurityException。

另一篇反射博客链接

Java反射基本玩法的更多相关文章

  1. 玩转java反射

    玩玩JAVA反射 什么是反射 Java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法:对于任何一个对象,都能够调用它的任何一个方法和属性:这样动态获取新的以及动态调用对象的方法 ...

  2. java反射原来是这么玩的(反射一开,谁都不爱)

    反射的发展历史 1996年01月23日,jdk 1.0版本发布,代号为Oak(橡树). 这个代号为Oak(橡树)的版本,在发布后的第二年,1997年02月19日,发布jdk 1.1版本,这次版本发布中 ...

  3. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...

  4. Java反射探索研究(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankakay 摘要:本文详细深入讲解是Java中反射的机制,并介绍了如何通过反射来生成对象.调用函数.取得 ...

  5. 深入解析Java反射基础

    博客原文:http://www.sczyh30.com/posts/Java/java-reflection-1/ - 这老哥写的特别好 一.回顾:什么是反射? 反射(Reflection)是Java ...

  6. JAVA反射机制及理解

    JAVA反射 往往当我们面对一项新的知识时,我们往往需要知道三个方面,它是什么,它能做什么,它比原有知识强在哪里,我们该怎么使用它.当你能够解决这些问题时,便意味着你已经对这项知识入门了. 首先: 反 ...

  7. 朱晔的互联网架构实践心得S2E4:小议微服务的各种玩法(古典、SOA、传统、K8S、ServiceMesh)

    十几年前就有一些公司开始践行服务拆分以及SOA,六年前有了微服务的概念,于是大家开始思考SOA和微服务的关系和区别.最近三年Spring Cloud的大火把微服务的实践推到了高潮,而近两年K8S在容器 ...

  8. 深入解析Java反射(1) - 基础

    深入解析Java反射(1) - 基础 最近正筹备Samsara框架的开发,而其中的IOC部分非常依靠反射,因此趁这个机会来总结一下关于Java反射的一些知识.本篇为基本篇,基于JDK 1.8. 一.回 ...

  9. Java反射机制demo(七)—反射机制与工厂模式

    Java反射机制demo(七)—反射机制与工厂模式 工厂模式 简介 工厂模式是最常用的实例化对象模式. 工厂模式的主要作用就是使用工厂方法代替new操作. 为什么要使用工厂模式?直接new不好吗? 直 ...

随机推荐

  1. WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解

    上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...

  2. android真机自动化测试

    appium执行用例时报错问题: 问题解析: 一般该种情况都是因为来连接了多个设备,验证办法:cmd->执行adb devices  看结果是否是多个devices ,如果是这个问题,停掉多余设 ...

  3. lintcode:线段树的构造

    线段树的构造 线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间.start和end都是整数,并按照如下的方式赋值: 根节点的 start 和 end 由 ...

  4. TCP非阻塞accept和非阻塞connect

    http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept     当一个已完成的连接准备好被accept的时候,select会把监 ...

  5. # 图解TCP/IP读书笔记(五)

    第五章.IP协议相关技术 IP旨在让最终目标主机收到数据包,但是在这一过程中仅仅有IP是无法实现通信的,因此还有需要作为为IP的辅助的各种协议支持. 协议 作用 特点 DNS(Domain Name ...

  6. 图解TCP/IP读书笔记(三)

    第三章.数据链路 数据链路层是计算机网络最基本的内容. 数据链路层的协议定义了通过通信媒介互连的设备之间传输的规范. 一.数据链路相关技术 1.MAC地址 关于MAC地址的几个要点: ①MAC地址长度 ...

  7. QT中显示GIF图片

    在QT中要显示GIF图片,不能通过单单的添加部件来完成. 还需要手动的编写程序. 工具:QT Creator 新建一个工程,我们先在designer中,添加一个QLabel部件. 如下图: 将QLab ...

  8. Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session--Make your app fanc ...

  9. Win8.1安装VirtualSVN Server发生service visualSVN Server failed to start解决办法

    Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for mo ...

  10. 实用Linux命令,不求最全但求实用-------磁盘使用情况du,df

    命令: df -h 输出实例: 文件系统             容量    已用  可用  已用% 挂载点 /dev/md0              9.7G  4.7G  4.6G  51% / ...