当前位置: 首页 > news >正文

河南网站建设高级私人定制制衣店

河南网站建设,高级私人定制制衣店,oa系统的概念,网站推广合作根据经验#xff0c;一般使用命令模式表明有些程序元素需要通过某种工具或者框架进行特殊处理。例如#xff0c;在Java4发行版本之前#xff0c;JUnit测试框架原本要求用户一定要用test作为测试方法名称的开头。这种方法可行#xff0c;但是有几个很严重的缺点。首先#…根据经验一般使用命令模式表明有些程序元素需要通过某种工具或者框架进行特殊处理。例如在Java4发行版本之前JUnit测试框架原本要求用户一定要用test作为测试方法名称的开头。这种方法可行但是有几个很严重的缺点。首先文字拼写错误会导致失败且没有任何提示。例如假设不小心将一个测试方法命名为tsetSafeyOverride而不是testSafeyOverride。JUnit3不会提示但也不会执行测试造成错误的安全感。命名模式的第二个缺点是无法确保它们只用于相应的程序元素上。例如假设将某个类称作TestSafeyMechanisms是希望JUnit3会自动地测试它所有地方法而不管它们叫什么名称。JUnit3还是不会提示但也同样不会执行测试。命名模式的第三个缺点是它们没有提供将参数值与程序元素关联起来的好方法。例如假设想要支持一种测试类别它只在抛出特殊异常时才会成功。异常类型本质上时测试的一个参数。你可以利用某种具体的命名模式将异常类型名称编码到测试方法中但是这样的代码很不雅观也很脆弱(见第62条)。编译器不知道要去检验准备命名异常的字符串是否真正命名成功。如果命名的类不存在或者不是一个异常你也要到试着运行测试时才会发现。注解很好的解决了所有这些问题JUnit从Java4开始使用。在本条目中我们要编写自己的试验测试框架展示一下注解的使用方法。假设想要定义一个注解类型来指定简单的测试它们自动运行并在抛出异常时失败。以下就是这样的一个注解类型命名为Test// Marker annotation type declarationimport java.lang.annotation.*;/*** Indicates that the annotated method is a test method. * Use only on parameterless static methods.*/Retention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)public interface Test {}Test注解类型的声明就是它自身通过Retention和Target注解进行了注解。注解类型声明的这种注解被称作元注解。Retention(RetentionPolicy.RUNTIME)元注解表明Test注解在运行时也应该存在否则测试工具就无法知道Test注解。Target(ElementType.METHOD)元注解表明Test注解只在方法声明中才是合法的它不能运用到类声明、域声明或者其他程序元素上。注意Test注解声明上方的注释“User only on parameterless static method”(只用于无参的静态方法)。如果编译器能够强制这一限制最好但是它做不到除非编写一个注解处理器让它来完成。关于这个主题的更多信息请参阅javax.annotation.processing的文档。在没有这类注解处理器的情况下如果将Test注解放在实例方法的声明中或者放在带有一个或者多个参数的方法中测试程序还是可以编译让测试工具运行时来处理这个问题。下面就是现实应用中的Test注解称作标记注解因为它没有参数只是标注被注解的元素。如果程序员拼错了Test或者Test注解应用到程序元素而非方法声明程序就无法编译// Program containing marker annotationspublic class Sample {Test public static void m1() { } // Test should passpublic static void m2() { }Test public static void m3() { // Test should failthrow new RuntimeException(Boom);}public static void m4() { }Test public void m5() { } // INVALID USE: nonstatic methodpublic static void m6() { }Test public static void m7() { // Test should failthrow new RuntimeException(Crash);}public static void m8() { }}Sample类有7个静态方法其中4个被注解为测试。这4个中有2个抛出了异常m3和m7另外两个则没有m1和m5。但是其中一个没有抛出异常的被注解方法m5是一个实例方法因此不属于注解的有效使用。总之Sample包含4项测试一项会通过两项会失败另一项无效。没有用Test注解进行标注的另外4个方法会被测试工具忽略。Test注解对Sample类的语义没有直接的影响。它们只负责提供信息供相关的程序使用。更一般的讲注解永远不会改变被注解代码的含义但是使它可以通过工具进行特殊的处理例如像这种简单的测试运行类// Program to process marker annotationsimport java.lang.reflect.*;public class RunTests {public static void main(String[] args) throws Exception {int tests 0;int passed 0;Class testClass Class.forName(args[0]);for (Method m : testClass.getDeclaredMethods()) {if (m.isAnnotationPresent(Test.class)) {tests;try {m.invoke(null);passed;} catch (InvocationTargetException wrappedExc) {Throwable exc wrappedExc.getCause();System.out.println(m failed: exc);} catch (Exception exc) {System.out.println(Invalid Test: m);}}}System.out.printf(Passed: %d, Failed: %d%n, passed, tests - passed);}}测试运行工具在命令行上使用完全匹配的类名并通过调用Method.invoke反射的运行的运行类中所有标注了Test注解的方法。isAnnotationPresent方法告知该工具运行哪些方法。如果测试方法抛出异常反射机制就会将它封装在InvocationTargetException中。该工具捕捉到这个异常并打印失败报告包含测试方法抛出的原始异常这些信息是通过getCause方法从InvocationTargetException中提取出来的。如果尝试通过反射测试方法时抛出InvocationTargetException之外的任何异常。表明编译时没有捕捉到Test注解的无效用法。这种用法包括实例方法的注解或者带有一个或多个参数的方法的注解或者不可访问的方法的注解。测试运行类中的第二catch块捕捉到这些Test用法错误并打印出相关的错误消息。下面就是RunTests在Sample上运行时打印的输出public static void Sample.m3() failed: RuntimeException: Boom Invalid Test: public void Sample.m5()public static void Sample.m7() failed: RuntimeException: Crash Passed: 1, Failed: 3现在我们要针对只在抛出特殊异常时才成功的测试添加支持。为此需要一个新的注解类型// Annotation type with a parameterimport java.lang.annotation.*;/*** Indicates that the annotated method is a test method that * must throw the designated exception to succeed.*/Retention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)public interface ExceptionTest {Class extends Throwable value();}这个注解的参数类型是Class extends Throwable。这个通配符类型有点绕口。它在英语中的意思是某个扩展Throwable的类的Class对象它允许注解的用户指定任何异常(或错误)类型。这种用法是有限制的类型令牌(详见第33条)的第一个示例。下面就是实际应用中的这个注解。注意类名称被用作了注解参数的值// Program containing annotations with a parameterpublic class Sample2 {ExceptionTest(ArithmeticException.class)public static void m1() { // Test should passint i 0;i i / i;}ExceptionTest(ArithmeticException.class)public static void m2() { // Should fail (wrong exception)int[] a new int[0];int i a[1];}ExceptionTest(ArithmeticException.class)public static void m3() { } // Should fail (no exception)}现在我们要修改一下测试运行工具来处理新的注解。这其中包括将以下代码添加到main方法中if (m.isAnnotationPresent(ExceptionTest.class)) {tests;try {m.invoke(null);System.out.printf(Test %s failed: no exception%n, m);} catch (InvocationTargetException wrappedEx) {Throwable exc wrappedEx.getCause();Class extends Throwable excType m.getAnnotation(ExceptionTest.class).value();if (excType.isInstance(exc)) {passed;} else {System.out.printf(Test %s failed: expected %s, got %s%n, m, excType.getName(), exc);}} catch (Exception exc) {System.out.println(Invalid Test: m);}}这段代码类似于用来处理Test注解的代码但有一处不同这段代码提取了注解参数的值并用它检验该测试抛出的异常是否为正确的类型。没有显式的转换因此没有出现ClassCastException的危险。编译过的测试程序确保它的注解参数表示的是有效的异常类型需要提醒一点有可能注解参数在编译时是有效的但是表示特定异常类型的类文件在运行时却不存在。在这种希望很少出现的情况下测试运行类会抛出TypeNotPresenException异常。将上面的异常测试示例再深入一点想象测试可以在抛出任何一种指定异常时能够通过。注解机制有一种工具使得支持这种用法变得十分容易。假设我们将ExceptionTest注解的参数类型改成Class对象的一个数组// Annotation type with an array parameterRetention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)public interface ExceptionTest {Class extends Exception[] value();}注解数组参数的语法十分灵活。它是进行过优化的单元素数组。使用了ExceptionTest新版的数组参数之后之前的所有ExceptionTest注解仍然有效并产生单元素的数组。为了指定多元素的数组要用花括号将元素包围起来并用逗号将它们隔开// Code containing an annotation with an array parameterExceptionTest({IndexOutOfBoundsException.class,NullPointerException.class })public static void doublyBad() {List list new ArrayList();// The spec permits this method to throw either// IndexOutOfBoundsException or NullPointerExceptionlist.addAll(5, null);}修改测试运行工具来处理新的ExceptionTest相当简单。下面的代码代替了原来的代码if (m.isAnnotationPresent(ExceptionTest.class)) {tests;try {m.invoke(null);System.out.printf(Test %s failed: no exception%n, m);} catch (Throwable wrappedExc) {Throwable exc wrappedExc.getCause();int oldPassed passed;Class extends Exception[] excTypes m.getAnnotation(ExceptionTest.class).value();for (Class extends Exception excType : excTypes) {if (excType.isInstance(exc)) {passed;break;}}if (passed oldPassed)System.out.printf(Test %s failed: %s %n, m, exc);}}从Java8开始还有另一种方法可以进行多值注解。它不是用一个数组参数声明一个注解类型而是用Repeatable元注解对注解的声明进行注解表示该注解可以被重复的应用个单个元素。这个元注解只有一个参数就是包含注解类型的类对象它唯一的参数是一个注解类型数组。下面的注解声明就是把ExceptionTest注解改成使用这个方法之后的版本。注意包含的注解类型必须利用适当的保留策略和目标进行注解否则声明将无法编译// Repeatable annotation typeRetention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)Repeatable(ExceptionTestContainer.class)public interface ExceptionTest {Class extends Exception value();}Retention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)public interface ExceptionTestContainer {ExceptionTest[] value();}下面是doublyBad测试方法用重复注解代替数组值注解之后的代码// Code containing a repeated annotationExceptionTest(IndexOutOfBoundsException.class)ExceptionTest(NullPointerException.class)public static void doublyBad() { ... }处理可重复的注解要非常小心。重复的注解会产生一个包含注解类型的合成注解。getAnnotationsByType方法掩盖了这个事实可以用于访问可重复注解类型的重复和非重复。但isAnnotationPresent使它变成了显式的即重复的注解不是注解类型(而是所包含的注解类型)的一部分。如果一个元素具有某种类型的重复注解并且用isAnnotationPresent方法检验该元素是否具有该类型的注解会发现它没有。用这种方法检验是否存在注解类型会导致程序默默的忽略掉重复的注解。同样的用这种方法检验是否存在包含的注解类型会导致程序默默的忽略掉非重复的注解。为了利用isAnnotationPresent检测重复和非重复的注解必须检查注解类型及其包含的注解类型。下面是Runtests程序改成使用ExceptionTest注解时有关部分的代码// Processing repeatable annotationsif (m.isAnnotationPresent(ExceptionTest.class) || m.isAnnotationPresent(ExceptionTestContainer.class)) {tests;try {m.invoke(null);System.out.printf(Test %s failed: no exception%n, m);} catch (Throwable wrappedExc) {Throwable exc wrappedExc.getCause();int oldPassed passed;ExceptionTest[] excTests m.getAnnotationsByType(ExceptionTest.class);for (ExceptionTest excTest : excTests) {if (excTest.value().isInstance(exc)) {passed;break;}}if (passed oldPassed) System.out.printf(Test %s failed: %s %n, m, exc);}}假如可重复的注解提升了源代码的可读性逻辑上是将同一个注解类型的多个实例应用到了一个指定的程序元素。如果你觉得它们增强了源代码的可读性就是用它们但是记住在声明和处理可重复注解的代码中会出现更多的样板代码并且处理可重复的代码容易出错。本条目中的测试框架只是一个试验。但它清楚的示范了注解相对于命名模式的优越性。这只是揭开了注解功能的冰山一角。如果是在编写一个需要程序员给源文件添加信息的工具就要定义一组适当的注解类型。既然有了注解就完全没有理由再使用命名模式了。也就是说除了“工具铁匠”(toolsmiths即平台框架程序员)之外大多数程序员都不必定义注解类型。但是所有的程序员都应该使用Java平台所提供的预定义的注解类型(详见第40条和第27条)。还要考虑使用IDE或者静态分析工具所提供的任何注解。这种注解可以提升由这些工具所提供的诊断信息的质量。但是要注意这些注解还没有标准化因此如果变换工具或者形成标准就有很多工作要做了。
http://www.zqtcl.cn/news/562126/

相关文章:

  • 一个大型网站建设得多少钱百度成都总部
  • 网站制作公司汉狮网络手机版网站优化
  • 铜川做网站logo 图标 设计
  • 如何做网站的注册页面南京宣传片公司有哪些
  • 中国建设机械教育协会网站网站建设中html中关于图片显示的标签有哪些
  • 网站过期后dede减肥网站源码
  • 营销型 手机网站网站建设方案后期服务
  • 怎么做一个个人网站建网站的八个步骤
  • 淘宝导购网站模版上海网站推广软件
  • 做影视网站引流湖北响应式网站建设费用
  • 网站统计cnzz网站空间有哪些
  • 泉州微信网站开发公司wordpress头像解决
  • 湛江网站建设皆选小罗24专业网站建设 福田
  • 厦门哪些做鲜花的网站门户网站开发设计报告
  • asp.net网站设计分工天津网站开发贴吧
  • 做多语言网站教程南宁vi设计公司
  • 百度联盟 网站备案wordpress 吾爱破解
  • 山西省建设厅网站首页网络营销推广为什么效果不好
  • 建材做网站好吗长沙做网站微联讯点不错
  • 建设小型网站分类门户网站系统
  • 文化馆网站数字化建设介绍138ip地址查询网站
  • 卖汽车的网站怎么做的建设服装网站的论文
  • 网络推广哪个网站好网站建设最低多少钱
  • 怎么在自己电脑做网站北京赛车网站开发
  • 门户网站内容wordpress上下页
  • 长安做英文网站营销型网站搭建
  • 网站开发交接清单seo排名优化方法
  • 各学院二级网站建设通报wordpress注册评论
  • 南通公司做网站无人在线完整免费高清观看
  • 廊坊网站推广局域网网站建设的步骤过程