• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

applet的参数化--对数组进行初始化(1)

发布: 2007-7-14 21:19 | 作者: 佚名    | 来源: 网络转载     | 查看: 73次 | 进入软件测试论坛讨论

领测软件测试网 摘要将 applet 参数化通常是一项烦琐的工作,包括在 applet 的 init() 方法中添加很多重复的代码行。上个月,Java 技巧的撰稿人 Yvon Sauvageau 向您讲述了如何将这些代码缩减为一行,这要归功于类反射机制。但是,他没有说明如何实现数组初始化。本技巧将说明使数组自动初始化的细节。 上个月,我在 Java Tip 57,"Applet parameterization via class reflection" 中提供了一个出色的方法来使 applet 参数化。参数化是指借助嵌入在 HTML 文件中的 PARAM 标记来传递参数。这个方法用起来很方便,因为它完成了全部的参数提取工作,使您在相当长的时间内不必输入 getParameter。但在上一篇技巧中我没提及如何实现数组初始化。本月的这篇技巧将为您讲述这个问题。 本文假定您比较熟悉类反射机制,尽管您可能在查看代码时就能对它有所了解。类反射机制的功能部件位于 java.lang.reflect 软件包内。这种机制使您能够检查类的结构,还可提供域、方法、访问修饰符等的运行时信息。 将列表数据提供给 applet 看过关于 applet 参数化的上一篇技巧的读者可能已经注意到:我们的方法没有对一类重要的对象进行初始化。在本文中,我们将研究如果利用类反射机制对一维数组和二位数组进行初始化。我知道只有实现对更高维数组的处理才能使狂热的科学家满意,但我将把那项工作作为练习留给您。 在我的上一篇技巧中,只能处理基本类型的数组和字符串数组。考虑到任何对象最终都能由基本数据类型和字符串构建而来,所以这将不会构成多大的限制。当然,很容易将我们的技术加以扩展,之后就能直接对其他类型的数据进行初始化。 数组是用来存储列表数据的理想数据结构。我们的技术使得向 applet 传递列表参数变得很简单。 通常利用动态生成 HTML 文档的程序(如 servlet 或 CGI 脚本)将列表数据传递给 applet。作为示例,我们设想一个比赛记分板 applet。HTML 生成器将会将当前的记分板数据库输出到 PARAM 标记中,接着相应的数组将被完全初始化 -- 这要归功于我们的参数提取方法。 列表数据项的语法 我们要实现的就是一个从 PARAM 标记中提取一维或是二维数组的方法。一维数组的语法是: PARAM NAME="myArray" VALUE="element1 element2 ... elementN" 各元素之间的定界符是空格。 二位数组的语法是: PARAM NAME="myMatrix" VALUE="element11 element12 element13 | element21 element22 element23 | element31 element32 element33" 各行之间的定界符是 | 符号。这里,myMatrix 是一个 (3 x 3) 数组。 注意:Java 支持不规则数组。 不规则数组就是各行的长度不同的数组。例如,HTML 作者可能会按以下方式输入帕斯卡三角形: PARAM NAME="pascalTriangle" VALUE=" 1 | 1 1 | 1 2 1 | 1 3 3 1 | 1 4 6 4 1 | 1 5 10 10 5 1 | 1 6 15 20 15 6 1" 初始化完成之后,pascalTriangle 域的内容将是: pascalTriangle[0] = {1} pascalTriangle[1] = {1, 1} pascalTriangle[2] = {1, 2, 1} pascalTriangle[3] = {1, 3, 3, 1} pascalTriangle[4] = {1, 4, 6, 4, 1} pascalTriangle[5] = {1, 5, 10, 10, 5, 1} pascalTriangle[5] = {1, 6, 15, 20, 15, 6, 1} 通常,程序员应该只声明 pascalTriangle,而不进行内存分配。我们的提取方法负责分配内存。但让我们假定已为第四行分配了内存,如下所示: pascalTriangle[3] = new int[2]; 我们的方法将只提取前两个元素。这样,第四行的初始化结果将是: pascalTriangle[3] = {1, 3} 数组知识回顾 正如您在以上代码清单中看到的那样,我们的方法实现有点“深奥”。因此,在研究源代码之前回顾有关数组的几点知识是个不错的主意。 我们都对 Java 的类型层次结构比较熟悉:Java 有一组预定义的基本数据类型(int、float...),还有 Object 的子类的一个继承树,Object 类是所有类的最终超类。但 Java 中还存在一个不很出名的平行层次结构,我称其为数组层次结构。您无论何时在类型层次结构中定义了一个新类型 Foo,您实际上也同时定义了一个自动结合到数组层次结构中的新类型 Foo[]。数组层次结构中的每个类(基本数据类型的数组除外)都是 Object[] 的子类。容易引起混淆的是:Object[] 和基本数据类型的数组都是 Object 的子类。图 1 表明了这一点。 图 1:两个平行的层次结构 令人感到奇怪的是,Java 根本就没有多维数组,只有一维数组。多维数组实际上是“一维数组的数组的数组的数组...”。因此,我们可以创建不规则数组。事实上,我们甚至可以不对某些行进行初始化,而将它们保留为空值。 数组提取方法的实现 现在我们可以查看源代码了。正如您所见,其中加了大量注释。通常,包含如此多的注释不是个好习惯,但在这里,我们要将已经抽象的 Java 数组包装在由类反射机制提供的元数据抽象层中。结果,多数程序语句都不能表明其自身的含义,所以在这种情况下对几乎每个代码行作注释是无可非议的。 无论何时对一维或是二维数组进行初始化,最终我们都需要用 HTML 作者输入的行对一维数组进行初始化。我们设计了一个方法来完成这一操作: /** * 用符号处理器 (tokenizer) 的内容填充一维数组。 * 符号被转换为数组的内容类型。 * * @param array 要填充的数组。 * @param elementTokens 包含要填入数组的符号的符号处理器。 */ private static void fillOneDimensionalArray(Object array, StringTokenizer elementTokens) throws IllegalAccessException { if (array != null && elementTokens != null && array.getClass().isArray()) { // 双重检验。 // 数组应该容纳哪种类型的元素? Class componentType = array.getClass().getComponentType(); int numElements = elementTokens.countTokens(); // 为数组元素赋值。 // // 请注意,我们确保索引不会超出范围。可能未给数组分配组足够的空间, // 以致无法容纳分析后的全部元素。 for (int j = 0; j < Array.getLength(array) && j < numElements; j++) { // 将符号转换为数组所容纳的类型。 // 然后将其添加到数组中。 if (componentType.equals(boolean.class)) Array.setBoolean(array, j, Boolean.valueOf(elementTokens.nextToken().trim()).booleanValue()); else if (componentType.equals(byte.class)) Array.setByte(array, j, Byte.valueOf(elementTokens.nextToken().trim()).byteValue()); else if (componentType.equals(char.class)) Array.setChar(array, j, elementTokens.nextToken().charAt(0)); else if (componentType.equals(double.class)) Array.setDouble(array, j, Double.valueOf(elementTokens.nextToken().trim()).doubleValue()); else if (componentType.equals(float.class)) Array.setFloat(array, j, Float.valueOf(elementTokens.nextToken().trim()).floatValue()); else if (componentType.equals(int.class)) Array.setInt(array, j, Integer.valueOf(elementTokens.nextToken().trim()).intValue()); else if (componentType.equals(long.class)) Array.setLong(array, j, Long.valueOf(elementTokens.nextToken().trim()).longValue()); else if (componentType.equals(short.class)) Array.setShort(array, j, Short.valueOf(elementTokens.nextToken().trim()).shortValue()); else if (componentType.equals(String.class)) Array.set(array, j, elementTokens.nextToken()); } } }

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网