解析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对象在某种程度上可以当作类似其他语言中的方法指针来使用,但是我们有更好的工具,尤其是接口、抽象类和嵌套类,可以用来处理那些通常在其他语言中用方法指针解决的问题。相关阅读:

win10 10547不能玩英雄联盟和穿越火线怎么办?

win10 mobile单手操作模式怎么用?win10 mobile和iOS系统单手操作区别对比

win10edge收藏夹保存在哪里 edge收藏夹导出图文步骤

web app与原生app的区别

node.js中的buffer.toString方法使用说明

Win10一周年更新设置更精美 新版设置应用界面

JavaSciprt中处理字符串之sup()方法的使用教程

php中jpgraph类库的使用介绍

在Linux中使用命令行进行文件覆盖的操作

详解Java的Spring框架中的注解的用法

win7系统连接WiFi发现上网信号很弱怎么办

Win10安装不了IE11浏览器怎么办 Win10系统Windows功能安装不了IE11的两种解决方法

重温JavaScript中的正则表达式 js学习笔记

javascript检测两个数组是否相似

java method field_java_解析Java中的Field类和Method类,Field类 Field类中定义了一些方 - phpStudy...相关推荐

  1. java读取codetable_解析Java对象的equals()和hashCode()的使用

    解析Java对象的equals()和hashCode()的使用 前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个.在多 ...

  2. java编译_解析 Java 即时编译器原理。

    ↑ 点击上面 "时代Java"关注我们,关注新技术,学习新知识! 一.导读 常见的编译型语言如C++,通常会把代码直接编译成CPU所能理解的机器码来运行.而Java为了实现&quo ...

  3. Java源码解析——Java IO包

    一.基础知识: 1. Java IO一般包含两个部分:1)java.io包中阻塞型IO:2)java.nio包中的非阻塞型IO,通常称为New IO.这里只考虑到java.io包中堵塞型IO: 2. ...

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

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

  5. java 字符串xml,解析java中的xml字符串?

    how do you parse xml stored in a java string object? Java's XMLReader only parses XML documents from ...

  6. c 解析java byte,深入解析Java编程中面向字节流的一些应用

    文件输入输出流 文件输入输出流 FileInputStream 和 FileOutputStream 负责完成对本地磁盘文件的顺序输入输出操作. [例]通过程序创建一个文件,从键盘输入字符,当遇到字符 ...

  7. japidocs怎么设置参数必填_JApiDocs 动态生成接口文档,并解析java 源码中的注释...

    1.介绍 JApiDocs 是一个符合 Java 编程习惯的 Api 文档生成工具.最大程度地利用 Java 的语法特性,你只管用心设计好接口,添加必要的注释,JApiDocs 会帮你导出一份漂亮的 ...

  8. java中注解的解析_全面解析Java中的注解与注释

    注解一.什么是 Annotation? (注解 or 注释)Annotation, 准确的翻译应该是 -- 注解. 和注释的作用完全不一样. Annotation 是JDK5.0及以后版本引入的一个特 ...

  9. java jsoup解析_3使用Jsoup解析Java中HTML文件的示例

    java jsoup解析 HTML是Web的核心,无论您是通过JavaScript,JSP,PHP,ASP或任何其他Web技术动态生成的,您在Internet上看到的所有页面都是基于HTML的. 您的 ...

最新文章

  1. 使用dstat命令的插件查看mysql的io状态
  2. javascript+dom
  3. 什么是java构造函数_什么是java构造函数
  4. 【重要】ES6-23 JavaScript模块化
  5. LateUpdate、Late、FixedUpdate的意义
  6. C#操作XmlDocument对象 报缺少根节点 一一道来
  7. The Power of Android Action Bars(转载)
  8. C#关键字扫盲——Tuple(元组类) 、ValueTuple(值元组)
  9. DB2 查看表空间使用率
  10. iOS开发者必备: 五大编程类工具
  11. 微信如何html动图文件,微信里的gif动态图片如何导出保存出来?看完本文你就知道了...
  12. Web自动化测试学习笔记
  13. 樱桃键盘驱动linux,樱桃键盘mx board9.0驱动
  14. 企业自动运行系统——定价策略
  15. 计算机通识培训,通识培训研修日志
  16. MT4软件IOS版如何下载
  17. 在CSDN中如何快速简单方便的免费下载资料
  18. 谷粒商城笔记+踩坑(18)——购物车
  19. 移动终端安全 顶级会议_顶级移动应用开发公司
  20. 使用JavaScrip实现简单问卷星快速生成自定义数据

热门文章

  1. gridsome(三)——plugins
  2. 小米oj 找到第 N 个数字 II
  3. 眼球追踪技术给各大科技巨头带来的四大应用前景
  4. [iOS开发]iPhoneX系列顶部和底部尺寸图解
  5. 网页转PDF文件工具——wkhtmltopdf
  6. Location is not available,the folder or directory is corrupted and unreadable
  7. 在程序中打开系统设置页
  8. 5个好用的Excel技巧,一秒钟完成一个功能
  9. 华为云发布桌面IDE-CodeArts
  10. MLCC(贴片)电容啸叫分析