Effective Java 35 Prefer annotations to naming patterns
Disadvantages of naming patterns
- Typographical errors may result in silent failures.
- There is no way to ensure that they are used only on appropriate program elements.
- 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();
}
- 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.
- 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.
- 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的更多相关文章
- 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 ...
- Effective Java 53 Prefer interfaces to reflection
Disadvantage of reflection You lose all the benefits of compile-time type checking, including except ...
- 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 ...
- Effective Java 18 Prefer interfaces to abstract classes
Feature Interface Abstract class Defining a type that permits multiple implementations Y Y Permitted ...
- Effective Java 20 Prefer class hierarchies to tagged classes
Disadvantage of tagged classes 1. Verbose (each instance has unnecessary irrelevant fields). 2. Erro ...
- Effective Java 25 Prefer lists to arrays
Difference Arrays Lists 1 Covariant Invariant 2 Reified at runtime Erased at run time 3 Runtime type ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- [git]fork+pull提交模式
fork+pull提交模式 在公司项目中,大多都是通过"主题分支"的方式,进行开发与合并代码.但是,这样又一个弊端就是:合并代码后需要删除分支.同时,如果是开源的项目的话,非项目中 ...
- Android 学习笔记之WebService实现远程调用+内部原理分析...
PS:终于可以抽出时间写写博客了,忙着学校的三周破实训外加替考...三周了,没怎么学习...哎... 学习内容: 1.WebService 实现远程方法的调用 什么是WebService... ...
- redis在centOS的安装
1.安装tcl支持 yum install tcl 2.安装redis我们以最新的2.8.9为例 $ wget http://download.redis.io/releases/redis-2.8. ...
- IOS开发UI基础UIActivityIndicatorView的属性
UIActivityIndicatorView 1.activityIndicatorViewStyle设置指示器的样式UIActivityIndicatorViewStyleWhiteLarge U ...
- phpBB论坛 代码 语法高亮 模块 Codebox Plus
phpBB代码语法高亮模块 Codebox Plus Code-By.Org (https://www.phpbb.com/customise/db/mod/codebox_plus/) (https ...
- ACM中的浮点数精度处理
在ACM中,精度问题非常常见.其中计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了.精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,让你debu ...
- 动态生成RDLC报表
前段时间,做了RDLC报表,主要是三块功能: 1.从DataGrid提取(包括最新的增删改)的数据,自动生成对应的RDLC报表文件(以流的形式驻存在内存中),用ReportViewer类来展示.打印. ...
- sql多行转一行,以逗号隔开
--SELECT ff= stuff((select ','+cast(WorkOrderNo as varchar)-- FROM dbo.TB_WorkOrder c -- where tpl.P ...
- elasticsearch 之IK分词器安装
IK分词器地址:https://github.com/medcl/elasticsearch-analysis-ik 安装好ES之后就可以安装分词器插件了 记住选择ES对应的版本 对应的有版本选择下载 ...
- HTML页面放大镜效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...