Java的反射机制Reflect
简介:
动态获取类的信息、动态调用对象的方法的功能叫做:Java 的反射(Reflection)机制。
Reflection是不同于C++等静态语言,而被视为准动态语言的关键性质。反射机制允许程序在运行时,透过Reflection API取得任何一个已知的class的内部信息,(功能列表)如:
- 得到类型修饰符public、private等。
- 得到其父类superclass, 其本身的类class。
- 实现了哪些interface也可以得到。
- 获得所有的field和method,并且可以在运行时,改变field的值、调用method,但是不能获得method的定义和实现 —— 即实例化这个类,生成这个类的对象。
通过反射机制,Java可以加载一个在运行时才获得名称的class,获悉其完整的构造,并生成对象(而这个对象是JVM生成的,即new Instance。相当于通过逆推,从计算机的角度完成了,人学习并使用一个类的功能。而这种能力的术语被称为introspection内省。
实现Reflect相关的类:
在JDK中,主要由以下类来实现反射机制(获取这些类的对象),这些类(除了第一个)都位于java.lang.reflect包中:
- Class类:代表一个类(即Class这个类存放Java的类:Class类的一个实例就是我们平常所说的一个类),位于java.lang包中。
- Field类:代表类的成员变量 / 属性。
- Method类:代表类的方法。
- Constructor类:代表类的构造方法。
- Array类:提供了动态创建数组,以及访问数组元素的静态方法等。
1、Class类(下面Class对象的概念和一般对象有点混乱):
Class类是整个反射机制的基础:一个类的所有对象,都对应于这个类,即一个Class对象而已。而实际上所有的类,或者说所有的Class对象都是由JVM生成。所以通过Class类的某些方法(对于Class类或者Class对象来说就是静态方法,对于不是Class对象的、一般的对象就是普通方法),可以获得指定的Class对象,也就是一个类的整个结构。之后就可以通过这个Class对象来操纵相应的类的一般对象。
Class对象不能通过new的方式创建,如上所说,有两种方法可以获取:
- 静态方法:Class clazz = Class.forName("java.lang.String");或者Class clazz = String.class;
- 普通方法getClass():String str = "";Class clazz = str.getClass(); —— 类是没有getClass方法的。
- public class TesterMain {
- public static void main(String[] args) {
- String pagename = "";
- try {
- //下面三种方法都是获得同一个Class对象:String
- Class c3 = Class.forName("java.lang.String");
- Class c1 = pagename.getClass();
- Class c2 = String.class;
- if(c1.equals(c2) && c1.equals(c3) && c2.equals(c3)) {
- System.out.println("test1");
- }
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
2、Field类:
一个类中的每个属性都对应于一个Field对象。
- import java.lang.reflect.Field;
- import Entity.Test;
- public class TesterMain {
- public static void main(String[] args) {
- try {
- //Test类:public String testPublic;private String testNonPublic;
- Class clazz = Test.class;
- // 一 :
- Field publicField = clazz.getField("testPublic");//获取指定的public属性
- Field everyWhereField = clazz.getDeclaredField("testNonPublic");//获取指定的任何属性(不论限定符)
- System.out.println(publicField + "\n" + everyWhereField);
- System.out.println("\n");
- //out:public java.lang.String Entity.Test.test
- //private java.lang.String Entity.Test.testNonPublic
- // 二 :
- Field[] publicFields = clazz.getFields();//获取Class对象中的所有public Field对象
- for (Field field : publicFields) {
- System.out.println(field);
- }
- Field[] allFields = clazz.getDeclaredFields();//获取所有的属性(不论限定符)
- for (Field field : allFields) {
- System.out.println(field);
- }
- } catch (SecurityException | NoSuchFieldException e) {
- e.printStackTrace();
- }
- }
- }
3、Method类(下面把Method对象对应的方法,简称为Method方法):
先给出示例代码,然后解释:
- String str = "hello";
- try {
- Method method = str.getClass().getMethod("charAt", int.class);//不能用Integer,因为charAt方法接收的是int,而int和Integer的Class对象是不一样的
- char c = (char) method.invoke(str, 1);
- System.out.println(c);
- } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- e.printStackTrace();
- }
通过Class对象,获得Method对象的方式:
- 按照方法名称 + 参数类型的Class对象列表,获得某个public Method对象(包括从父类或接口继承的方法):Method getMethod(String methodName,Class<?> ... parameterTypes)。
- 获得所有的public方法(包括继承的方法):Method [] getMethods()。
- 若不论方法的限定符,对应的有:getDeclaredMethod(String methodName,Class<?> ... parameterType)和 getDeclaredMethods()。
使用Method对象:
invoke方法,用于调用Method方法,函数原型为:Object invoke(Object obj,Object ... obj),参数一:原本调用Method方法的对象,参数二:Method方法的实参列表。 —— 因此,若Method方法是static的,则参数一为null。
4、Constructor类:
5、Array类:
最后,通过反射得到了Class对象,那么就可以用Class对象构造出对应的类的实例:
- // 一 :默认构造函数:String string1 = new String();
- Class clazz = String.class;
- String string1 = (String) clazz.newInstance();
- // 二:指定的构造函数(不一定带参,自适应):String string2 = new String("hello reflect");
- Constructor constructor = clazz.getConstructor();
- String string2 = (String) constructor.newInstance("hello reflect");
- System.out.println(string1 + "\n" + string2);
- //out:空字符串
- //hello reflect
Java的反射机制Reflect的更多相关文章
- Java反射机制(Reflect)解析-----https://www.cnblogs.com/fzz9/p/7738381.html
Java反射机制(Reflect)解析-----https://www.cnblogs.com/fzz9/p/7738381.html
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- Java高新技术 反射机制
Java高新技术 反射机制 知识概要: (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...
- Java基础-反射(reflect)技术详解
Java基础-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类加载器 1>.JVM 类加载机制 如下图所示,JVM类加载机制分为五个部分 ...
- java的反射机制浅谈(转)
原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- 【转】Java利用反射机制访问私有化构造器
Java利用反射机制访问私有化构造器 博客分类: java 我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...
- 【转】java原理—反射机制
一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言 ...
随机推荐
- いろはちゃんとマス目 / Iroha and a Grid (组合数学)
题目链接:http://abc042.contest.atcoder.jp/tasks/arc058_b Time limit : 2sec / Memory limit : 256MB Score ...
- netperf 网络性能测试
Netperf是一种网络性能的测量工具,主要针对基于TCP或UDP的传输.Netperf根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求 ...
- ul点击li,增加样式
用户首次绑定后,需要选择一款头像 <!--imgList头像列表--><el-row class="regModel1"> <el-col :span ...
- shell 多行注释 块注释
转自 https://www.cnblogs.com/emanlee/p/3749911.html 1 : ' 被注释的多行内容 ' 2 :<<eof 被注释的多行内容 eof 3 :&l ...
- String小案例(**)、包装类型和普通数据类型的转换(拆装箱)
###String用法: package StringTest; /**功能: * 判断Java文件名是否正确,判断邮箱格式是否正确 * 其中:合法的文件名应该以.java结尾 * 合法的邮箱名至少包 ...
- linux下nginx整合php
在nginx中药使用php可不像apache那样,因为apache是把php当做自己的一个模块来启动的, 而我们的nginx是把http请求转发给php程序,也就是说,php和nginx是相互独立的的 ...
- Linux查看机器和硬盘的SN
查看硬件RAID中某块硬盘SN # sas 口: [root@ ~]$ smartctl -a /dev/sda -d megaraid,n *** Serial number: 6RJ974SR * ...
- ELK日志分析系统
部署环境 192.168.1.147 kibana.logstash.Escluster-node-1 192.168.1.151 filebeat.Escluster-node-2.nginx 软件 ...
- 深入理解softmax函数
Softmax回归模型,该模型是logistic回归模型在多分类问题上的推广,在多分类问题中,类标签 可以取两个以上的值.Softmax模型可以用来给不同的对象分配概率.即使在之后,我们训练更加精细 ...
- 使用ccache大幅度加速gcc编译速度至少1倍以上(不需要修改任何编译选项)
因为我们整个项目都是使用c++开发的,生成的so足有50M,原来编译一遍要三五分钟,一个针对oracle,一个针对mysql,整个轮回下来这部分就要10来分钟,加上代码上传.翻译,一轮配管打包下来二三 ...