最代码官方的gravatar头像
最代码官方 2014-11-18 17:27:43

java自定义注解实例

In this tutorial, we will show you how to create two custom annotations – @Test and @TestInfo, to simulate a simple unit test framework.

在这篇教程中,我们将示范如何新建两个自定义的标注: @Test和@TestInfo,并模拟一个简单的单元测试框架。

P.S This unit test example is inspired by this official Java annotation article.

这个单元测试例子的灵感来自于oracle官方文章。

1. @Test Annotation

This @interface tells Java this is a custom annotation. Later, you can annotate it on method level like this @Test(enable=false).

这个@interface标识java程序,这是一份自定义标注。之后,你可以在方法级别上标注它就像这样@Test(enable=false)

Test.java

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

Note
Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.

注意

方法申明必须不能带有任何参数或throws片段,返回类型限制为基本类型,字符串String,类Class,枚举eunms,标注和这些类型的数组

2. @TesterInfo Annotation

This @TesterInfo is applied on class level, store the tester details. This shows the different use of return types – enum, array and string.

@TesterInfo应用到类级别,保存tester的详情。这个类演示返回不同的类型:enum, array and string

TesterInfo.java

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";
 
}

3. Unit Test Example

Create a simple unit test example, and annotated with the new custom annotations – @Test and @TesterInfo.

新建一个简单的单元测试实例,并且通过新建的标注来标注:@Test and @TesterInfo

TestExample.java

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.
	  }
	}
 
}

4. Java reflection – Read the Annotation

Below example show you how to use Java reflection APIs to read and process the custom annotations.

下面的例子演示如何通过java反射来读取和处理自定义标注。

RunTest.java

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

Output

Testing...
 
Priority :HIGH
CreatedBy :mkyong.com
Tags :sales, <strong>test</strong>
LastModified :03<strong>/</strong>01<strong>/</strong><span style="color:#000000">2014</span>
 
<span style="color:#000000">1</span> - Test <span style="color:#ff0000">'testA'</span> - failed: java.lang.RuntimeException: This <strong>test</strong> always failed 
<span style="color:#000000">2</span> - Test <span style="color:#ff0000">'testC'</span> - passed 
<span style="color:#000000">3</span> - Test <span style="color:#ff0000">'testB'</span> - ignored
 
Result : Total : <span style="color:#000000">3</span>, Passed: <span style="color:#000000">1</span>, Failed <span style="color:#000000">1</span>, Ignore <span style="color:#000000">1</span>

原文:http://www.mkyong.com/java/java-custom-annotations-example/


打赏

最代码最近下载分享源代码列表最近下载
最代码最近浏览分享源代码列表最近浏览
fuyouou  LV5 2023年7月7日
ewan007  LV29 2022年7月8日
xb1406112453  LV5 2021年4月15日
dongzhan  LV12 2020年12月8日
simple丶余心  LV21 2020年9月16日
newhaijun  LV15 2020年5月27日
lvagoni  LV2 2020年4月30日
月之氏族  LV23 2019年12月8日
luohaipeng  LV23 2019年12月3日
阿昌先生  LV13 2019年5月15日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友