Disadvantages of naming patterns

  1. Typographical errors may result in silent failures.
  2. There is no way to ensure that they are used only on appropriate program elements.
  3. They provide no good way to associate parameter values with program elements.

Naming patters example

testXXX

textXXXWithXXXException

Better solution: meta-annotations

// Marker annotation type declaration

import java.lang.annotation.*;

/**

* Indicates that the annotated method is a test method.

* Use only on parameter less static methods.

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Test {

}

/**

* 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 Exception> value();

}

/**

* Annotation type with an array parameter

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface MultiExceptionTest {

Class<? extends Exception>[] value();

}

  1. The @Retention(RetentionPolicy.RUNTIME) meta-annotation indicates that Test annotations should be retained at runtime. Without it, Test annotations would be invisible to the test tool.
  2. The @Target(ElementType.METHOD)meta-annotation indicates that the Test annotation is legal only on method declarations: it cannot be applied to class declarations, field declarations, or other program elements.
  3. The parameter definition Class<? extends Exception> value(); and Class<? extends Exception>[] value(); declare the required one or more exceptions to be generated by the method.

// Program containing marker annotations

public class Sample {

@Test public static void m1() { } // Test should pass

public static void m2() { }

@Test public static void m3() { // Test Should fail

throw new RuntimeException("Boom");

}

public static void m4() { }

@Test public void m5() { } // INVALID USE: nonstatic method

public static void m6() { }

@Test public static void m7() { // Test should fail

throw new RuntimeException("Crash");

}

public static void m8() { }

}

/**

* @author Kaibo

* Program containing annotations with a parameter.

*/

public class Sample2 {

@ExceptionTest(ArithmeticException.class)

public static void m1() { // Test should pass

int 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)

}

/**

* @author Kaibo

*

*/

public class Sample3 {

// Code containing an annotation with an array parameter

@MultiExceptionTest({ IndexOutOfBoundsException.class,

NullPointerException.class })

public static void doublyBad() {

List<String> list = new ArrayList<String>();

// The spec permits this method to throw either

// IndexOutOfBoundsException or NullPointerException

list.addAll(5, null);

}

}

/**

* @author Kaibo

* Program to process marker annotations.

*/

import java.lang.reflect.*;

public class RunTests {

public static void main(String[] args) throws Exception {

Class<?> testClass = Class.forName(args[0]);

testSample1(testClass);

testClass = Class.forName(args[1]);

testSample2(testClass);

testClass = Class.forName(args[2]);

testSample3(testClass);

}

private static void testSample1(Class<?> testClass) {

int tests = 0;

int passed = 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);

}

/**

* @param testClass

*/

private static void testSample2(Class<?> testClass) {

int tests = 0;

int passed = 0;

for (Method m : testClass.getDeclaredMethods()) {

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 Exception> 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);

}

}

}

System.out.printf("Passed: %d, Failed: %d%n", passed, tests - passed);

}

private static void testSample3(Class<?> testClass) {

int tests = 0;

int passed = 0;

for (Method m : testClass.getDeclaredMethods()) {

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();

Class<? extends Exception>[] excTypes = m.getAnnotation(

MultiExceptionTest.class).value();

int oldPassed = passed;

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);

}

}

}

System.out.printf("Passed: %d, Failed: %d%n", passed, tests - passed);

}

}

Summary

There is simply no reason to use naming patterns now that we have annotations. All programmers should, however, use the predefined annotation types provided by the Java platform(Item 36 and Item24).

Effective Java 35 Prefer annotations to naming patterns的更多相关文章

  1. Effective Java 69 Prefer concurrency utilities to wait and notify

    Principle Use the higher-level concurrency utilities instead of wait and notify for easiness. Use Co ...

  2. Effective Java 53 Prefer interfaces to reflection

    Disadvantage of reflection You lose all the benefits of compile-time type checking, including except ...

  3. Effective Java 68 Prefer executors and tasks to threads

    Principle The general mechanism for executing tasks is the executor service. If you think in terms o ...

  4. Effective Java 18 Prefer interfaces to abstract classes

    Feature Interface Abstract class Defining a type that permits multiple implementations Y Y Permitted ...

  5. Effective Java 20 Prefer class hierarchies to tagged classes

    Disadvantage of tagged classes 1. Verbose (each instance has unnecessary irrelevant fields). 2. Erro ...

  6. Effective Java 25 Prefer lists to arrays

    Difference Arrays Lists 1 Covariant Invariant 2 Reified at runtime Erased at run time 3 Runtime type ...

  7. Effective Java 46 Prefer for-each loops to traditional for loops

    Prior to release 1.5, this was the preferred idiom for iterating over a collection: // No longer the ...

  8. Effective Java 49 Prefer primitive types to boxed primitives

    No. Primitives Boxed Primitives 1 Have their own values Have identities distinct from their values 2 ...

  9. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

随机推荐

  1. Nginx+CI出现404错误

    最近刚学ci框架,做了个简单的项目,在本地搭服务器的环境都调通了,但是部署到远程服务器时: http://example.com/(index.php)/ 可以访问(为配置的默认controller- ...

  2. css知识

    margin和padding是什么意思 margin外边距,padding内边距,外边距表示一个元素的边到相邻元素的距离,内边距表示元素之间的内容和元素边框的距离. font:12px/1.5 表示什 ...

  3. ASP.NET MVC 在控制器中接收视图表单POST过来的数据方法

    方法一:通过Request.Form [HttpPost]        public ActionResult Test()        {            string id=Reques ...

  4. AutoTransformHandler

    public static ObservableCollection<F> Transform<T, F>(List<T> target) where F : ne ...

  5. asp.net学习之Repeater控件

    asp.net学习之Repeater控件 文章摘自:http://www.cnblogs.com/shipfi/archive/2009/10/19/1585703.html Repeater控件和D ...

  6. csharp:Chart

    http://www.dotnetperls.com/chart using System; using System.Windows.Forms; using System.Windows.Form ...

  7. 百度FIS入门

    1.fis作为nodejs的模块来管理的,所以首先得安装nodejs,看我前面的安装nodejs的文章. 2.官方的案例下载包https://github.com/hefangshi/fis-quic ...

  8. Mongoose 框架初学使用记录

    嘛.... 最近由于需要使用HTTP服务端,原先是使用的Qt框架实现的HTTP服务端,然后发现有些缺陷导致我不得不放弃这个框架,也不是完全放弃,只是HTTP服务端这里不再使用Qt,用Qt做高并发真的有 ...

  9. mysql查询今天,昨天,近7天,近30天,本月,上一月数据的方法(摘录)

    mysql查询今天,昨天,近7天,近30天,本月,上一月数据的方法分析总结: 话说有一文章表article,存储文章的添加文章的时间是add_time字段,该字段为int(5)类型的,现需要查询今天添 ...

  10. 两种设计模式(1)==>>“简单工厂”

    我们以做一个计算器为例,给大家介绍简单工厂的应用: 效果: 这里我们使用 继承 ,虚方法, 简单工厂的设计模式来完成 首先,我们除了搭好窗体外,我们应该把我们的一些类准备好: 1.计算的父类Calcu ...