当前位置: 首页 > 编程日记 > 正文

Java学习总结:39(反射机制)

反射机制

JAVA中反射是动态获取信息以及动态调用对象方法的一种反射机制。
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态语言的一个关键性质。Java反射的功能是在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,在运行时判断任意一个类所具有的成员变量和方法,在运行时调用任意一个对象的方法,生成动态代理。反射是Java中最为重要的特性,几乎所有的开发框架以及应用技术都是基于反射技术的应用。

认识反射

在一个程序中如果要通过对象取得这个对象所在类的信息,可以通过Object类中的getClass()方法(public final Class<?>getClass())实现。
例:反射初步操作

package Project.Study.Reflect;import java.util.Date;public class Test1 {public static void main(String[]args){Date date=new Date();				//产生实例化对象System.out.println(date.getClass());//直接反射输出对应类的信息}
}
//结果:
//class java.util.Date

Class类对象实例化

当我们使用getClass()方法时,返回的类型为java.lang.Class,这是反射操作的源头类,即所有的反射操作都需要从此类开始,而最关键的是这个类有以下3种实例化方式。

一.调用Object类中的getClass()方法,但是如果要使用此类操作必须要有实例化对象。

该方法往往出现在简单Java类与提交参数的自动赋值操作中,像Struts、Spring MVC都会提供表单参数与简单Java类的自动转换。

例:

package Project.Study.Reflect;import java.util.Date;public class Test2 {public static void main(String[]args){Date date=new Date();               //产生实例化对象Class<?>cls=date.getClass();        //通过实例化对象取得Class对象//Class类中定义有“public String getName()”方法可以取得类的完整名称System.out.println(cls.getName());  //直接对象所在类的名称}
}
//结果:
//java.util.Date

二.使用“类.class”取得,此时可以不需要通过指定类的实例化对象取得

该方式往往是将反射操作的类型设置交由用户使用,像Hibernate中进行数据保存以及根据ID查询中会使用到此类操作。

例:

package Project.Study.Reflect;public class Test3 {public static void main(String[]args){Class<?>cls=java.util.Date.class;   //通过类名称取得Class类对象System.out.println(cls.getName());  //直接对象所在类的名称}
}
//结果:
//java.util.Date

三.调用Class类提供的方法:public static Class<?>forName(String className)throws ClassNotFoundException。

该方法可以实现配置文件以及Annotation配置的反射操作,几乎所有的开发框架都是依靠此方式实现的。

例:

package Project.Study.Reflect;public class Test4 {public static void main(String[]args) throws Exception {//此处直接传递了一个要进行反射操作类的完整名称,是用字符串定义的Class<?>cls=Class.forName("java.util.Date");System.out.println(cls.getName());          //直接对象所在类的名称}
}
//结果:
//java.util.Date

反射实例化对象

掌握了Class类对象实例化的三种操作方式,我们现在就可以利用Class类来进行类的反射控制了。

Class类的常用方法

No.方法类型描述
1public static Class<?>forName(String className) throws ClassNotFoundException普通通过字符串设置的类名称实例化Class类对象
2public Class<?>[] getInterfaces()普通取得类实现的所有接口
3public String getName()普通取得反射操作类的全名
4public String getSimpleName()普通取得反射操作类名,不包括包名称
5public Package getPackage()普通取得反射操作操作类所在的包
6public Class<? super T>getSuperclass()普通取得反射操作类的父类
7public boolean isEnum()普通反射操作的类是否是枚举
8public boolean isInterface()普通反射操作的类是否是接口
9public boolean isArray()普通反射操作的类是否是数组
10public T newInstance() throws InstantiationException,IllegalAccessException普通反射实例化对象

在Class类中最重要的一个方法就是newInstance()方法,通过此方法可以利用反射实现Class类包装类型的对象实例化操作,也就是说即使不使用关键字new也可以进行对象的实例化操作。
注意:如果利用newInstance()方法反射实例化对象,则类中一定要提供无参构造方法,否则会出现语法错误。

例:利用反射实例化对象

package Project.Study.Reflect;class Book{public Book(){System.out.println("该类的无参方法");}@Overridepublic String toString(){return "Hello World";}
}
public class Test5 {public static void main(String[]args) throws Exception {Class<?>cls=Class.forName("Project.Study.Reflect.Book");//设置要操作对象的类名称//反射实例化后的对象返回的结果都是Object类型Object object=cls.newInstance();                        //相当于使用new调用无参结构Book book=(Book)object;                                 //向下转型System.out.println(book);}
}
//结果:
//该类的无参方法
//Hello World

上程序中的newInstance()方法返回的类型为Object,如果有需要则可以利用对象的向下转型操作将其强制变为子类实例进行操作。
可能会有人问使用newInstance()方法进行对象的实例化有什么好处,直接用new它不香吗?
其实因为关键字new实例化对象需要明确地指定类的构造方法,故new是造成耦合的最大元凶,所以使用newInstance()方法实例化对象可以实现更好的解耦合操作

使用反射调用构造

使用Class类中的newInstance()方法虽然可以实现反射实例化对象操作,但是这样的操作本身有一个限制,就是操作对象的类中必须提供无参的构造方法。

例:错误示例

package Project.Study.Reflect;class Book2{private String title;private double price;public Book2(String title,double price){this.price=price;this.title=title;}@Overridepublic String toString(){return "图书名称:"+this.title+",价格:"+this.price;}
}
public class Test6 {public static void main(String[]args) throws Exception {Class<?>cls=Class.forName("Project.Study.Reflect.Book2");Object object=cls.newInstance();System.out.println(object);}
}
//结果:
//Exception in thread "main" java.lang.InstantiationException: Project.Study.Reflect.Book2
//	at java.base/java.lang.Class.newInstance(Class.java:585)
//	at Project.Study.Reflect.Test6.main(Test6.java:18)
//Caused by: java.lang.NoSuchMethodException: Project.Study.Reflect.Book2.<init>()
//	at java.base/java.lang.Class.getConstructor0(Class.java:3350)
//	at java.base/java.lang.Class.newInstance(Class.java:572)
//	... 1 more

所以,当类中没有提供无参构造方法的时候,就必须通过java.lang.reflect.Constructor类来实现对象的反射实例化操作。(java.lang.reflect是所有反射操作类的程序包)

取得类中的构造方法

No.方法类型描述
1public Constructor<?>[] getConstructors() throws SecurityException普通取得全部的构造方法
2public Constructor< T >[] getConstructors(Class<?>…parameterTypes) throws NoSuchMethodException, SecurityException普通取得指定参数类型的构造方法

Constructor类的常用操作方法

No.方法类型描述
1public Class<?>[] getExceptionTypes()普通返回构造方法上所有抛出异常的类型
2public int getModifiers()普通取得构造方法的修饰符
3public String getName()普通取得构造方法的名字
4public int getParameterCount()普通取得构造方法中的参数个数
5public Class <?>[] getParameterTypes()普通取得构造方法中的参数类型
6public T newInstance(Object…initargs) throws InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException普通调用指定参数的构造实例化对象

注意:因为修饰符是用数字描述的,所有的修饰符都是一个数字,所以取得修饰符的方法返回的是int类型。

例:明确调用类中的有参构造

package Project.Study.Reflect;import java.lang.reflect.Constructor;class Book3{private String title;private double price;public Book3(String title,double price){this.title=title;this.price=price;}@Overridepublic String toString(){return "图书名称:"+this.title+",价格:"+this.price;}
}
public class Test6 {public static void main(String[]args)throws Exception{Class<?>cls=Class.forName("Project.Study.Reflect.Book3");//明确地找到Book3类中两个参数的构造,第一个参数类型是String,第二个是doubleConstructor<?>constructor=cls.getConstructor(String.class,double.class);Object object=constructor.newInstance("Java",79.9);     //实例化对象System.out.println(object);}
}//结果:
//图书名称:Java,价格:79.9

上程序的思路:
1.首先利用Class类对象取得此构造方法(返回Constructor类对象);
2.然后利用Constructor类中的newInstance()方法传递指定的数据,就可以调用有参构造进行对象的反射实例化。

反射调用方法

Class类取得普通方法的操作

No.方法类型描述
1public Method[] getMethods() throws SecurityException普通取得类中的全部方法
2public Method[] getMethod(String name,Class<?>…parameterTypes) throws NoSuchMethodException,SecurityException普通取得类中指定方法名称与参数类型的方法

注:反射操作中,每一个方法都通过java.lang.reflect.Method类表示。

Method类的常用方法

No.方法类型描述
1public int getModifiers()普通取得方法的修饰符
2public Class<?> getReturnType()普通取得方法的返回值类型
3public int getParameterCount()普通取得方法中定义的参数数量
4public Class<?> getParameterTypes()普通取得方法中定义的所有参数类型
5public Object invoke(Object obj,Object…args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException普通反射调用方法并且传递执行方法所需要的参数数据
6public Class<?> getExceptionTypes()普通取得方法抛出的异常类型

例:使用反射操作简单Java类的属性

package Project.Study.Reflect;import java.lang.reflect.Method;class Book4{private String title;public void setTitle(String title){this.title=title;}public String getTitle() {return title;}
}
public class Test7 {public static void main(String[]args)throws Exception{String fieldName="Title";Class<?>cls=Class.forName("Project.Study.Reflect.Book4");Object object=cls.newInstance();//取得类中的setTitle()方法Method setMet=cls.getMethod("set"+fieldName,String.class);//取得类中的getTitle()方法,本方法不接收参数并且没有返回值类型说明Method getMet=cls.getMethod("get"+fieldName);setMet.invoke(object,"Java书");      		//等价于Book4类对象.setTitle("Java书");System.out.println(getMet.invoke(object));  //等价于Book4类对象.getTitle();}
}
//结果:
//Java书

反射调用成员

Class类中取得成员的操作

No.方法类型描述
1public Field[] getDeclaredFields() throws SecurityException普通取得本类定义的全部成员
2public Field[] getDeclaredFields(String name) throws NoSuchFieldException,SecurityException普通取得本类指定名称的成员
3public Field[] getFields() throws SecurityException普通取得本类继承父类的全部成员
4public Field[] getField(String name) throws NoSuchFieldException,SecurityException普通取得本类继承父类中指定名称的成员

Field类的常用方法

No.方法类型描述
1public Class<?> getType()普通取得改成员的类型
2public Object get(Object obj) throws IllegalAccessException,IllegalArgumentException普通取得指定对象中的成员的内容,相当于直接调用成员
3public void set(Object obj,Object value) throws IllegalAccessException,IllegalArgumentException普通设置指定对象中的成员内容,相当于直接利用对象调用成员设置内容

注意:不管使用反射调用的是普通方法还是调用类中的成员,都必须存在实例化对象(可以依靠反射取得实例化对象),因为类中的属性必须在类产生实例化对象后才可以使用。

例:利用反射直接操作私有成员

package Project.Study.Reflect;import java.lang.reflect.Field;class Book5{private String title;
}
public class Test8 {public static void main(String[]args)throws Exception{Class<?>cls=Class.forName("Project.Study.Reflect.Book5");   //取得反射对象Object object=cls.newInstance();                            //必须给出实例化对象Field titleField=cls.getDeclaredField("title");     //取得类中的title属性titleField.setAccessible(true);                             //取消封装,使title属性可以被外界访问titleField.set(object,"Java书");                            //相当于:Book5类对象.title="数据"System.out.println(titleField.get(object));                 //相当于:Book5类对象.title}
}
//结果:
//Java书

相关文章:

perl 编程 - 判断系统进程是否活着的方法

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a;我在使用perl编写CGI程序时遇到的一些问题&#xff0c;解决以后&#xff0c;记录一下我的心得&#xff0c;有心的朋友们会从中得到帮助并养成正确使用的好习惯。 perl编程中判断系统进程是否存活的方法…

2009 Competition Highlights by ICPC Live

2009 Competition Highlights by ICPC Live Links&#xff1a;http://www.youtube.com/watch?vn0oZRcAz6w0 转载于:https://www.cnblogs.com/yewei/archive/2012/09/07/2674862.html

C4D灯光照明技术学习教程

C4D的灯光照明技术 大小解压后&#xff1a;4.8G 学会用Redshift点亮3D场景&#xff0c;像专业人士一样塑造光线 灯光在任何空间都是至关重要的&#xff0c;无论是真实的还是虚拟的。它能够传递某种感觉或情感。平面设计师罗伯托冈萨雷斯观察到如此重要的方面&#xff0c;并将其…

Java学习总结:40(国际化)

国际化 所谓国际化程序指的是同一套程序代码可以在不同的国家使用&#xff0c;可以根据其应用的国家自动在项目中显示出本国的相应文字信息。 使用Locale类定义语言环境 Locale类的常用方法 No.方法类型描述1public Locale(String language,String country)构造设置使用的语…

AFNetWorking 队列请求

我们在开发过程中&#xff0c;经常会遇到有些页面不止一个网络请求&#xff0c;有时候需要两个三个甚至更多&#xff0c;这个时候我们就需要队列请求&#xff0c;下边是GET请求的多个请求放在队列里边&#xff1a; [objc] view plaincopyprint? NSURL *url [NSURL URLWithStr…

Hadoop-虚拟机环境准备

传送门&#xff1a;https://app.yinxiang.com/fx/4fdf4d09-ddc8-4c67-8bf7-cca1c913fce5

WCF实现RESTFul Web Service

共同学习了前面一些概念&#xff0c;终于开始正题了哈。RESTful的Web Service调用直观&#xff0c;返回的内容容易解析。这里先会描述一个简单的场景--Web Service提供一个方法来搜索个人信息&#xff0c;传入人名&#xff0c;返回完整个人信息。下面我们一步步用WCF实现一个RE…

VS QT插件

支持用VS编译qt工程 QT下载页&#xff1a;http://qt-project.org/downloads qt-vs-addin插件: http://download.qt-project.org/official_releases/vsaddin/qt-vs-addin-1.2.2-opensource.exe 转载于:https://www.cnblogs.com/Leo-Forest/p/3507017.html

使用AutoCAD 2021创建真实世界的土木设计项目

由工程组织创建|最后更新日期:2021年9月 时长:7h 24m | 7节| 64节讲座|视频:1280720&#xff0c;44 KHz | 大小解压后3 GB 流派:电子学习|语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 学会快速使用AutoCAD &#xff1b;专业地制作真实世…

Java学习总结:41(文件操作类:File)

Java文件操作类&#xff1a;File 在java.io包中&#xff0c;如果要进行文件自身的操作(例如&#xff1a;创建、删除等)&#xff0c;只能依靠java.io.File类完成。 File类的常用操作方法 No.方法类型描述1public File(String pathname)构造传递完整文件操作路径2public File(F…

关于大型网站技术演进的思考(四)-存储的瓶颈4

如果数据库需要进行水平拆分&#xff0c;这其实是一件很开心的事情&#xff0c;因为它代表公司的业务正在迅猛的增长&#xff0c;对于开发人员而言那就是有不尽的项目可以做&#xff0c;虽然会感觉很忙&#xff0c;但是人过的充实&#xff0c;心里也踏实。 数据库水平拆分简单说…

2022-2028年中国环卫行业产业链深度调研及投资前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国环卫行业市场行业相关概述、中国环卫行业市场行业运行环境、分析了中国环卫行业市场行业的…

curl命令具体解释

对于windows用户假设用Cygwin模拟unix环境的话&#xff0c;里面没有带curl命令&#xff0c;要自己装&#xff0c;所以建议用Gow来模拟&#xff0c;它已经自带了curl工具&#xff0c;安装后直接在cmd环境中用curl命令就可&#xff0c;由于路径已经自己主动给你配置好了。 linux …

如何修改配置以修复ThinkPad 小红帽滚轮失效?

本人使用ThinkPad X1 Carbon超级本&#xff0c;由于近期安装了遨游浏览器(Maxthon)&#xff0c;发现其总体体验还是不错&#xff0c;但是在本机器上有个明显的Bug&#xff1a;就是小红帽的滚轮不管用。 由于就查了网上相关资料并加以试验&#xff0c;最终得以解决&#xff0c;方…

在虚幻引擎5中重塑火箭联盟——口袋联盟

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:3.28 GB |时长:4h 21m 了解如何实现火箭联盟般的力学&#xff0c;并在短时间内创建最近的火箭…

Java学习总结:42(字节流和字符流)

字节流与字符流 上一节我们学习了文件操作类File&#xff0c;但是File类虽然可以操作文件&#xff0c;但是却不能操作文件的内容。如果要进行文件内容的操作&#xff0c;就必须依靠流的概念来完成。流在实际中分为输入流和输出流两种&#xff0c;输入流和输出流是一种相对的概…

用C#钩子写一个改键外挂

我的微信群——软件开发测试工程师交流群&#xff0c;欢迎扫码&#xff1a; 改键是一种习惯&#xff0c;比如在玩儿lol或者dota的时候。理论上玩儿什么游戏都可以改键。 做一个窗体&#xff08;点击Install——应用改键&#xff0c;点击Uninstall——撤销应用&#xff09;&…

Spring中WebApplicationContext

ApplicationContext是Spring的核心&#xff0c;Context我们通常解释为上下文环境&#xff0c;我想用“容器”来表述它更容易理解一 些&#xff0c;ApplicationContext则是“应用的容器”了:P&#xff0c;Spring把Bean放在这个容器中&#xff0c;在需要的时候&#xff0c;用getB…

洛谷 P1966 火柴排队

题意 给定2个等长序列a、b&#xff0c;要求通过交换使 \[\sum_{i1}^{n}(a_i-b_i)^2\] 最小。 分析 看着这个式子&#xff0c;我突然想到了方差。很明显&#xff0c;方差反应数据的波动程度&#xff0c;所以让数据集中就可以使方差变小了。而对应到这个公式&#xff0c;大方向就…

Revit结构2021-2022从零到精通

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:8.6 GB 含课程文件 |时长:14h 46m 涵盖Revit结构2021-2022的基本、中级和高级功能 Revit Str…

BZOJ1922: [Sdoi2010]大陆争霸

题目&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id1922 带限制最短路。 每个点真正的dis是max(dis[i],dis[v]),v是其保护点。 可以把题目中的保护转化为每个点的贡献。 每次扫一边连出的边做最短路把rd为0的点加入队列。 再扫一遍自己的贡献&#xff0c;更新它…

Java学习总结:43(转换流)

转换流 字节流和字符流的转换可以通过InputStreamReader、OutputStreamWriter两个类转换&#xff0c;下面是这两个类的继承结构和构造方法 名称定义构造构造方法InputStreamReaderpublic class InputStreamReader extends Readerpublic InputStreamReader(InputStream in)Out…

2022-2028年中国环保服务业投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国环保服务行业市场行业相关概述、中国环保服务行业市场行业运行环境、分析了中国环保服务行…

一个build.xml实例

<?xml version"1.0"?> <project name"ssh" basedir"." default"usage"> <property name"name" value"ssh"/> <property name"war.dir" value"war"/> &l…

Spring Boot 2.0 常见问题总结(一)

SpringBoot2.x 依赖环境和版本新特性说明 依赖版本 jdk8 以上, Springboot2.x 用 JDK8 , 因为底层是 Spring framework5 。jar 包方式运行 SpringBoot 项目时问题 打包成jar包&#xff0c;需要增加maven依赖。 <build><plugins><plugin><groupId>org.s…

UE4场景设计学习教程

视频:MPEG4视频(H264) 19201080 25fps 1400kbps |音频:AAC 44100Hz立体声128kbps 语言&#xff1a;西班牙语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:35节课(6小时36分钟) 文件大小:4.7 GB 学会使用这个强大的软件的工具&#xff0c;一步一步地创造…

Java学习总结:44(文件复制案例)

案例&#xff1a;文件复制(针对InputStream和OutputStream的操作应用) 流程图(比较复杂我就不敲了&#xff0c;直接拍出来) 例&#xff1a;实现文件复制操作 package Project.Study.FileCopyCase;import java.io.*;public class Test {public static void main(String[]args…

java多态的理解

Java中多态性的实现 什么是多态 面向对象的三大特性&#xff1a;封装、继承、多态。从一定角度来看&#xff0c;封装和继承几乎都是为多态而准备的。这是我们最后一个概念&#xff0c;也是最重要的知识点。多态的定义&#xff1a;指允许不同类的对象对同一消息做出响应。即同一…

2022-2028年中国高密度聚乙烯(HDPE)行业市场发展调研及投资前景分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国高密度聚乙烯(HDPE)行业市场行业相关概述、中国高密度聚乙烯(HDPE)行业市场行业运行环境、…

计算机视觉图像处理机器学习压缩感知等论文代码大全

点击链接进入相关博文 1.来自西弗吉利亚大学li xin整理的CV代码合集 主要包括&#xff1a; 1.图像去噪&#xff0c;编码&#xff0c;去马赛克&#xff0c;超分辨&#xff0c;分割&#xff0c;去模糊&#xff0c;纹理合成&#xff0c;修复&#xff0c;质量评估等 2.视频编码和目…