引用:[Java Custom Annotations Example]{http://www.mkyong.com/java/java-custom-annotations-example/}
在android 的開源項(xiàng)目butterknife,使用注解的方式店溢,解放了android中view的注入飒泻,下面通過一個(gè)列子學(xué)習(xí)一下注解祈秕。
在這個(gè)例子中牺弄,向你展示怎樣創(chuàng)建兩個(gè)自定義注解Annotation---@Test和@TestInfo, 進(jìn)行單元測(cè)試
1:@Test 注解
這個(gè)@interface告訴java這個(gè)一個(gè)自定義的注解嗽元,然后你可以使用這個(gè)注解在類的方法上使用障般,例如:@Test(enable=false).
package com.mkyong.test.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) //can use in method only.
public @interface Test {
//should ignore this test?
public boolean enabled() default true;
}
筆記:
@Retention,@Target 都是元注解,(用來標(biāo)注注解的注解叫做元注解)
@Retention(RetentionPolicy.RUNTIME) 表示運(yùn)行時(shí)也保留該注解
@Target(ElementType.METHOD) 表示只能在方法的上面使用它,如果是ElementType.TYPE就表示在類的上面使用默勾。
2.@TesterInfo 注解
這個(gè)@TesterInfo自定義注解應(yīng)用到類上袍镀,這個(gè)展示了其中方法返回的不同類型,有枚舉闽巩,數(shù)組钧舌,字符串等
package com.mkyong.test.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) //on class level
public @interface TesterInfo {
public enum Priority {
LOW, MEDIUM, HIGH
}
Priority priority() default Priority.MEDIUM;
String[] tags() default "";
String createdBy() default "Mkyong";
String lastModified() default "03/01/2014";
}
@Target(ElementType.TYPE) 表示只能就表示在類的上面使用。
3: 單元測(cè)試的例子
使用自定義的@Test涎跨,和@TesterInfo洼冻,在這個(gè)測(cè)試?yán)又小?/strong>
package com.mkyong.test;
import com.mkyong.test.core.Test;
import com.mkyong.test.core.TesterInfo;
import com.mkyong.test.core.TesterInfo.Priority;
@TesterInfo(
priority = Priority.HIGH,
createdBy = "mkyong.com",
tags = {"sales","test" }
)
public class TestExample {
@Test
void testA() {
if (true)
throw new RuntimeException("This test always failed");
}
@Test(enabled = false)
void testB() {
if (false)
throw new RuntimeException("This test always passed");
}
@Test(enabled = true)
void testC() {
if (10 > 1) {
// do nothing, this test always passed.
}
}
}
上面的例子中,@Testinfo用在類上隅很,@test用在方法上
4. 反射獲取注解
下面的這個(gè)例子撞牢,通過反射的api,去讀取自定義注解的信息
package com.mkyong.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.mkyong.test.core.Test;
import com.mkyong.test.core.TesterInfo;
public class RunTest {
public static void main(String[] args) throws Exception {
System.out.println("Testing...");
int passed = 0, failed = 0, count = 0, ignore = 0;
Class<TestExample> obj = TestExample.class;
// Process @TesterInfo
if (obj.isAnnotationPresent(TesterInfo.class)) {
Annotation annotation = obj.getAnnotation(TesterInfo.class);
TesterInfo testerInfo = (TesterInfo) annotation;
System.out.printf("%nPriority :%s", testerInfo.priority());
System.out.printf("%nCreatedBy :%s", testerInfo.createdBy());
System.out.printf("%nTags :");
int tagLength = testerInfo.tags().length;
for (String tag : testerInfo.tags()) {
if (tagLength > 1) {
System.out.print(tag + ", ");
} else {
System.out.print(tag);
}
tagLength--;
}
System.out.printf("%nLastModified :%s%n%n", testerInfo.lastModified());
}
// Process @Test
for (Method method : obj.getDeclaredMethods()) {
// if method is annotated with @Test
if (method.isAnnotationPresent(Test.class)) {
Annotation annotation = method.getAnnotation(Test.class);
Test test = (Test) annotation;
// if enabled = true (default)
if (test.enabled()) {
try {
method.invoke(obj.newInstance());
System.out.printf("%s - Test '%s' - passed %n", ++count, method.getName());
passed++;
} catch (Throwable ex) {
System.out.printf("%s - Test '%s' - failed: %s %n", ++count, method.getName(), ex.getCause());
failed++;
}
} else {
System.out.printf("%s - Test '%s' - ignored%n", ++count, method.getName());
ignore++;
}
}
}
System.out.printf("%nResult : Total : %d, Passed: %d, Failed %d, Ignore %d%n", count, passed, failed, ignore);
}
}
結(jié)果:
Testing...
Priority :HIGH
CreatedBy :mkyong.com
Tags :sales, test
LastModified :03/01/2014
1 - Test 'testA' - failed: java.lang.RuntimeException: This test always failed
2 - Test 'testC' - passed
3 - Test 'testB' - ignored
Result : Total : 3, Passed: 1, Failed 1, Ignore 1
先是獲取類上的注解@TesterInfo的信息叔营,然后獲取方法上的注解@Test的信息
其中在android stuido中運(yùn)行java文件屋彪,可以在android項(xiàng)目的單元測(cè)試中編寫,然后運(yùn)行就好绒尊。