method java_解析Java中的Field类和Method类

Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值。将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特定对象或类的字段。

getGenericType方法返回表示字段的声明类型的Type实例。对于像String或int这样的平凡类型,该方法将返回与其相关联的Class对象,例如String.class和int.classo对于像List < Stri ng>这样的参数化类型,该方法将返回Parameterizedrype的实例,例如,对像T这样的类型,该方法将返回Typevariable实例。

遗留下来的getType方法将返回字段的类型的Class对象。对于平凡类型,该方法的行为与getGenericType方法的相同。如果字段的声明类型是参数化类型,那么getType方法将返回参数化类型的擦除所对应的Class对象,即原始类型的Class对象。例如,对于声明为List < Stri ng>的对象,getType将返回Li St. class的。如果字段的声明类型是类型变量,那么getType方法将返回类型变量的擦除所对应的class对象。例如,假设有一个类FOO,对于其声明为T类型的字段,get丁ype将返回object.

class对象。如果FOO被声明为FOo,那么get下ype将返回 Number.class.

我们可以使用isEnumConstant方法查询一个字段是否是枚举常量,也可以使用get和set方法来获取和设置字段的值。这些接受object引元并返回Obj ect值的方法都有一种通用形式,以及一些可以直接处理基本类型的更加特化的形式。所有这些方法都要接受一个引元,用来指定所要操作的对象。对于静态字段,将忽略这个对象引元,所以此时也可以将其设

置为null。下面的方法将打印一个对象的short型字段的值:

public static void printShortField(Object o, String name)

throws NoSuchFieldException,IllegalAccessException

{

Field field=o.getClass().getField(name);

short value=(Short) field.get(o);

System.out.println(value);

get方法的返回值可以是这个字段所引用的任何对象,如果该字段是基本类型,那么该方法将返回恰当类型的包装器类对象。对于我们的”hort型字段,get方法将返回包含该字段值的short类型的对象,而在将它赋值给本地变量value时,该对象值会自动进行拆箱转换。

set方法的使用也是类似的。将short型字段设置为所提供的值的方法看起来可能像下面这样:

public static voi

setShortField(Object o,String name,short nv)

throws NoSuchFieldException,IllegalAccessException

Field field=0.getClass().getField(name);

field .set(o .nv);

虽然set接受的是Object类型的参数,但是我们可以直接传递一个short型的值,并用包装转换将其包装为short类型的对象。

在上面的方法中,如果指定对象的域是不可访问的,并且这种访问权限控制是强制执行的,那么就会抛出IllegalACcessException异常;如果传递的对象与该域的类型不同,就会抛出illegalArgumentException异常;如果该域是非静态的且传递的对象引用是null,就会抛出NullPointerException异常;访问静态域可能会要求对类进行初始化,所以该方法也会抛出ExceptionInInitializerError异常。

Field类还有特定的用来获取和设置基本类型的方法,例如,我们可以在Field对象上调用getPrimitive7ype和set Primitive7ype,其中Primitive7ype是(首字母大写的)基本类型名。get方法可用于下面的语句:

short value=field.getshort(o);

而set方法可用于下面的语句:

field.setshort(o, nv);

用以上两种方式声明的语句中可以避免使用包装器类对象。

Field类实现了AnnotatedElement接口,所以我们也可以像16.2节那样查询应用于域

上的注解。

凭借上面介绍的方法,我们可以将Field对象用作操纵任意值的一种方式,但是我们应该尽量避免使用它。因为Java语言会在程序的编译期尽可能多地捕获编程错误,所以在我们编写代码时,使用的诸如「ield对象这样的间接方法越少,那么在将它们编译成代码之前,就可以防止更多的错误。而且,我们可以看到,在前面的代码中,要想知道到底会发生什么,与在普通的语法中直接使用域名的情况相比,我们花费在阅读代码上的精力显然大了许多。

Final字段

在通常情况下,对声明为final的字段进行设置将会导致抛出IllegalACcessException

异常,这是我们所能预期的,因为final字段的值是永远不会改变的。但是有些特殊情况—例如在定制的反序列化(见20.8.4节)中,改变final字段的值就是有意义的,我们只有在实例字段上才能通过反射实现这一点,并且前提是在该Field对象上已经调用过了setAccessible(true)。注意,可以成功调用setAccessible(true)是不够的,必须确实调用过它。

这种能力是为高度特化的上下文提供的,并非用于通用目的,我们介绍它仅仅是为了保持内容的完整性。如果脱离了特定的上下文,例如定制的反序列化,那么改变final字段的值可能会导致意外的甚至是灾难性的后果。在这些上下文之外,不能保证对final字段的改变是可见的。即便是在这样的上下文中,在使用这项技术编码时也必须保证安全机制不会阻碍代码的执行。改变值为常量变量(见2.2.3节)的final字段将会导致此改变不可见,除非通过使用反射来实现这种修改。

Method类method类和它从member类继承而来的方法使得我们可以获得方法声明的完整信息:

" public Type getGenericReturnTypeO:该方法返回的是目标方法的返回类型的Type对象。如果目标方法被声明为返回void,则该方法返回void.classo

" public Type[] getGenericParameterTypes():该方法返回目标方法所有参数类型的Type对象数组,这些Type对象将按照参数的声明顺序存储于在数组中。如果目标方法没有任何参数,则该方法返回一个空数组。

.publ i c Type [] getGeneri caccepti onTypes Q:该方法返回在throws子句中列出的所有异常类型的Type对象数组,这些Type对象将按照异常的声明顺序存储在数组中。

如果目标方法没有声明任何异常,则该方法返回一个空数组。

Java还提供了getReturnType,getParameterTypes和getExceptionTypes方法,用来返回Cl as”对象而不是Type对象。就像在使用Field.getType时,参数化类型和类型变量是由它们的擦除所对应的Class对象表示的。

method类实现了AnnotatedElement,并且我们可以像16.2节所讨论的那样去查询应用于方法上的注解。另外,Method类还提供了getParameterAnnotations,用来提供对应用于方法参数上的注解进行访问。getParameterAnnotations方法可以返回Annotation数组,其中最外层数组的每一个元素都与方法的参数相对应;如果某个参数没有任何注解,则该方法为这个参数返回一个长度为0的Annotation数组。如果method对象所表示的方法自身就是一个注解元素,那么getDefaultvalue方法将返回一个表示该元素默认值的Object对象;如果method对象本身不是注解元素或者它没有默认值,则该方法将返回null.Method类也实现了GenericDeclaration,因此定义了getTypeParameters方法,该方法将返回一个Typevariable对象数组。如果给定的method对象表示的不是泛型方法,该方法将返回一个空数组。

我们可以使用isvarArgs方法来检查某个method对象是否是一个可变引元方法,而i sBridge方法可以用来检查它是否是一个桥接方法

Method对象最有趣的用法就是反射地调用它自己:

.public object invoke(object onThis,object…args)throws IllegalACcessException,IllegalArgumentException,工nvocation下argetException:该方法在onThis对象上调用method对象定义的方法,并用args的值来设置被调用方法的参数。对于非静态方法,onThis的实际类型就确定了将要调用方法的哪种实现,而对于静态方法,onThis会被忽略,并且通常会设置为null. args值的数量必须和被调用方法的实际参数数量相同,并且这些值的类型必须全部都可赋值给那些被调用方法的参数;否则,我们将会得到工llegalArgumentException异常。请注意,可变引元方法的最后一个参数是一个数组,所以我们必须用实际想要传递的“可变”引元来填充该数组。如果我们想调用我们没有访问权限的方法,该方法就会抛出IllegalACcessException异常。如果被调用方法不是on下his对象的方法,该方法会抛出工llegalArgumentExcepti on异常。如果onThis为null并且是非静态的,该方法就会抛出NO 1PointerException异常。如果这个 method对象表示的是静态方法,并且声明这个静态方法的类仍处于待初始化状态,该方法就会抛出ExceptionIn工nitializerError异常。如果被调用法出异幂,谈万法就会抛出InvocationTargetException异常。

当我们使用invoke方法时,可以直接传递基本类型,也可以使用合适的包装器类。包装器类表示的类型必须可赋值给方法所声明的参数类型。我们可以使用Long,Float或Double来包装double类型的引元,但是不能用Double来包装long或float类型的引元,因为double不是可赋值给long或们oat的。对invoke方法返回的object的处理方法和Field.get一样,都是返回对应于它们的包装器类的基本类型。如果方法声明为void, invoke方法将返回null,

简单地说,就是我们在用invoke来调用方法时,只能使用在Java语言中合法的与其参数

具有相同类型和值的引元。例如,下面的调用

return str.indexof(".”,8);

可以用反射写成如下形式:

Throwable fa们ure;

try{

Method indexM=String.class.

getMethod("index0f",String.class,int.class);

return (Integer) indexM.invoke(str,”,”,8);

}catch (NoSuchMethodException e){

failure=e;

}catch (InvocationTargetException e){

fa们ure=e .getCause();

}catch (IllegalAccessException e){

failure=e;

}

throw fa们ure;

虽然编译器对于直接调用所做的安全性检查,在使用反射的情况下,只能在运行时使用invoke时进行,但是基于反射的代码确实拥有与直接调用的代码在语义上等效的安全性检查。访问权限检查可能会以略为不同的方式执行—安全管理器可能会拒绝访问我们的包中的某个方法,即使我们可以直接调用该方法。

当我们可以使用这种形式的调用时,我们有充分的理由去避免它。但是如果我们在编写调试器或其他需要将用户输入解释为对对象操作的泛型应用时使用invoke或get/set方法,就会显得很合理。method对象在某种程度上可以当作类似其他语言中的方法指针来使用,但是我们有更好的工具,尤其是接口、抽象类和嵌套类,可以用来处理那些通常在其他语言中用方法指针解决的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

a股历史30年的大盘价_2020年7月30日大盘走势分析

2020年7月30日大盘走势分析严正声明&#xff1a;分析下面小程序炒股广告与本公众号zyh218642无关&#xff0c;纯属第三方平台自然生成&#xff0c;不要点开&#xff0c;谨防上当受骗。7月份大盘走势分析7月份大盘的多空压力与支撑位置&#xff1a;…第二压力&#xff1a;3139.0…

java 做ui_【原创】JavaApplication的UI也可以做的很美

最近在做Java Application的项目&#xff0c;对于ui的美观&#xff0c;做了一些尝试。有幸看到了JGoodIdes的LookAndFeel包。效果大家可以看看如下连接http://www.jgoodies.com经过试验&#xff0c;解决了中文乱码问题&#xff0c;下面将经验和大家共分享。LookAndFeel如同css一…

python低代码_几行代码搞定ML模型,低代码机器学习Python库正式开源

PyCaret 库支持在「低代码」环境中训练和部署有监督以及无监督的机器学习模型&#xff0c;提升机器学习实验的效率。想提高机器学习实验的效率&#xff0c;把更多精力放在解决业务问题而不是写代码上&#xff1f;低代码平台或许是个不错的选择。最近&#xff0c;机器之心发现了…

java if else重构_java – 如何重构这个有多个if / else语句的方法

我有一种感觉,这个if / else应该被重构,但我不确定我能做什么,或者我是否应该让它像它一样……private String someReportUrl(HttpServletRequest request, HttpServletResponse response) {String url;if (isBackToReportsSummary(request)) {url SUMMARY_PAGE;getReportsSum…

vue2.0 唤起百度地图app_开车选高德,出门靠百度,高德百度地图APP对比

高德和百度是在电子地图领域竞争的对手&#xff0c;但是&#xff0c;在同一领域他们的发展方向的侧重也存在差异。那么&#xff0c;他们究竟有什么不同呢&#xff1f;当然&#xff0c;他们的开发人员必须是不同的&#xff0c;肯定不用考虑。此外&#xff0c;在某些数据和功能上…

java beanutil 工具类_实现BeanFactoryAware来达到Spring静态方法获取Bean对象的BeanUtil工具类...

在容器初始化时注入Bean工厂&#xff0c;并提供一些列静态方法&#xff0c;用于运行期间任何地方都可以用过他来获许对应Beanpackage com.idaima.util;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.spri…

火力发电厂与变电站设计防火标准_真题—火力发电厂1

做真题&#xff0c;遇真题&#xff0c;解真题1、某燃煤火力发电厂&#xff0c;单机容量200MW&#xff0c;该发电厂火灾自动报警系统的下列设计方案中&#xff0c;正确的是()。A.运煤系统内的火灾探测器防护等级为IP65B.厂区设置集中报警系统C.消防控制室与集中控制室分别独立设…

bigdecimal 判断是否为数字_C语言判断字符串是否为回文

回文就是字符串中心对称&#xff0c;如“abcba”、“abccba”是回文&#xff0c;“abcdba”不是回文。/*判断字符串是否为回文*/ #include <stdio.h> int main(void) {int i,k;char line[10];/*输入字符串*/printf("Enter a string:");k0;while((line[k]getcha…

java文件学生_文件存储学生信息(JavaIO流)

package com;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Scanner;/*** author Administrator*1.要求&#xff1a;有五个学生&#xff0c;每个学生有姓名、年龄 、成绩三个属性&a…

捷波朗STORM耳机设置中文_2020年 除了Airpods pro以外无线降噪蓝牙耳机如何选?五款热门入耳式蓝牙降噪耳机推荐...

双十二红包&#xff0c;每日三次&#xff0c;手慢无2020 年除了Airpods pro 以外&#xff0c;五款热门入耳式无线蓝牙降噪耳机简评近期&#xff0c;Apple推出的新款无线耳机Air pods pro引起了一波数码控的热议&#xff0c;大致分为两个立场&#xff0c;我个人专门去苹果店试听…

java如何画百分比圆环_canvas绘制百分比圆环进度条

开发项目&#xff0c;PM会跟踪项目进度&#xff1b;完成某个事情&#xff0c;也可以设置一个完成的进度。这里用canvas绘制一个简单百分比圆环进度条。看下效果&#xff1a;1. 动画方式2. 静默方式贴上代码&#xff0c;仅供参考/*** LBS drawRing* Date: 2015-04-24* * opts.pa…

python单链表操作、建立头指针为h的单链表_在一头指针为H的单链表中,若要向表头插入一个由指针p指向的结点,则应执行( )操作。 (5.0分)_学小易找答案...

【单选题】【简答题】什么叫消费者市场?【单选题】安全生产管理模式九个不中的“三不准”指 :【单选题】在一个单链表中,若要在p所指向的结点之后插入一个新结点,则需要相继修改( )个指针域的值。 (5.0分)【单选题】TCP坐标出厂时默认位于哪里?【多选题】在通常情况下,下列哪…

mysql填写账户远程_mysql账户添加远程访问

我们要将root账户设置为远程可访问mysql> show databases;--------------------| Database |--------------------| here || information_schema || mysql || performance_schema || sys |--------------------选择mysql数据库mysql> use mysql;Reading table informatio…

java密码框提示_[Java教程]如何实现在密码框如出现提示语

[Java教程]如何实现在密码框如出现提示语02015-12-25 13:00:14如何实现在密码框如出现提示语:有时候我们需要在登陆表单有一些提示语言&#xff0c;比如“请输入用户民”和“请输入密码”等语言&#xff0c;至于用户名好说&#xff0c;但是在密码框中出现“请输入密码”这样的语…

linux 休眠定时唤醒_Linux重启关机命令经验之谈

请关注本头条号&#xff0c;每天坚持更新原创干货技术文章如需学习视频&#xff0c;请查看本头条号简介&#xff0c;免费在线观看学习视频一般来说&#xff0c;Linux服务器都保存着重要文件和服务&#xff0c;不当使用将可能导致数据丢失甚至是灾难。同样&#xff0c;正确的关闭…

java formfile_基于Struts文件上传(FormFile)详解

Struts中FormFile用于文件进行上传1.在jsp文件中进行定义名字&#xff1a;头像:2.在Form表单中定义FormFile/** Generated by MyEclipse Struts* Template path: templates/java/JavaClass.vtl*/package com.yourcompany.struts.form;import javax.servlet.http.HttpServletReq…

空白世界地图打印版_考研准考证打印什么时候_中国研究生招生信息网官网

考研准考证打印什么时候_中国研究生招生信息网官网由广东研究生考试网考试快讯栏目由提供&#xff0c;更多关于考研准考证打印入口,广东研究生考试快讯的内容&#xff0c;请关注广东研究生考试频道/广东人事考试网&#xff01;2021考研人注意啦!2021考研准考证下载时间及入口12…

debian java7_Debian 7 和 Debian 8 用户怎样安装 Oracle Java 8

Oracle Java 8 稳定版本近期已发布&#xff0c;有很多新的特征变化。其中&#xff0c;有功能的程序支持通过“Lambda项目 ”&#xff0c;收到了一些安全更新和界面改进上的bug修复&#xff0c;使得开发人员的工作更容易。本文将告诉你如何在Debian 7 “Wheezy”和Debian 8 “Je…

python创建虚拟环境venv_Python 3 使用venv创建虚拟环境

Python 3.3以上使用venv来代替了原来Python2使用的virtualenv创建虚拟环境。虚拟环境的作用是使得不同项目的Python包之间不会相互干扰&#xff0c;避免了由此产生的各种问题。现在演示下如何在桌面创建一个虚拟环境C:\Users\dell\Desktop>mkdir python3VenvTestC:\Users\de…

jdbc java连接oracle_java连接oracle jdbc连接

Class.forName("oracle.jdbc.driver.OracleDriver");Connection ctDriver.Magager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl","scott","tiger");java连接oracle odbc桥连接&#xff1a;Class.forName("sun.jdbc.odb…