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. 一起Polyfill系列:让Date识别ISO 8601日期时间格式

    一.什么是ISO 8601日期时间格式 ISO 8601是国际标准化组织制定的日期时间表示规范,全称是<数据存储和交换形式·信息交换·日期和时间的表示方法>. 示例: 1. 2014-12 ...

  2. Rest(Restful)风格的Web API跟RPC风格的SOAP WebService--这些名词都啥意思?

    经常看到这些词汇,也有baidu或google过,但记忆里总是模糊,不确定,以至于别人问及的时候,总说不清楚.开篇随笔记录下.大家有补充或者意见的尽请留文. 本文顺序: 一.Rest(Restful) ...

  3. sprint2 项目部署+展示

    项目展示网址: http://160q49b998.51mypc.cn/ (注:所有用户密码都为123456,校内断网时访问不了)

  4. 非链接方式访问数据库--查询的数据集用Dataset来存储。

    private void Button_Click_1(object sender, RoutedEventArgs e) { //非链接方式访问数据库, //1创建连接对象(连接字符串) using ...

  5. ASP.NET MVC5---通过QueryString传值

    1.首先我们来看看普通的传值是啥样的.如图所示,我们普通的传值是这样的 public ActionResult Edit(int?id) { if (id == null) { return new ...

  6. 新学C#线程使用总结

    这两天在项目上需要使用多线程技术,研究了半天,碰到了一些问题,现在简要总结下. 线程的使用其实很简单,和JAVA里面差不多,但是还是有很多特别的地方,在C#中的线程,如果要对非线程创建的控件进行操作的 ...

  7. 2 Orchard汉化资源包的使用

    Orchard安装完毕之后我们就可以在后台尝试做一些基本的操作感受下Orchard提供的一些功能,比如添加一个页面.菜单.文章什么的.也可以试着新建一些部件.布局之类的感受下.个人建议摆弄一下了解下就 ...

  8. Discuz!X3解读之类引入机制及目录结构

    实例: - /source/class/table/table_forum_faq.php - /source/class/model/model_forum_post.php - /source/p ...

  9. C# on Visual Studio Code

    installation Download .NET Core SDK installer and install it. https://www.microsoft.com/net/download ...

  10. hibernate4整合spring3事务问题

    本文是作者在对hibernate4+spring3+struts2整合中遇到的一个问题.对s2sh进行了基本的整合搭建以后,就是对事务的控制管理,将hibernate的事务交由spring管理.根据网 ...