目录
反射获取Annotation
可以通过反射获取注解信息。
常用方法:
方法 | 说明 |
---|---|
public A getAnnotation(Class annotationClass) | 获取指定类型的Annotation |
public Annotation[] getAnnotations() | 获取全部的Annotation |
public A[] getAnnotationsByType(Class annotationClass) | 得到拥有指定类型的Annotation |
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) | 判断是否存在指定的Annotation注解 |
示例:
public class TestAnnotation {
public static void main(String[] args) throws NoSuchMethodException {
String value = "com.tx.test.annotation.MessageImpl";
IMessage message = Factory.getInstance(value);
message.send("www.baidu.com");
System.out.println("------------------------------------");
Annotation[] annotations = IMessage.class.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
System.out.println("------------------------------------");
Annotation[] annotationsTest = MessageImpl.class.getAnnotations();
for (Annotation annotation : annotationsTest) {
System.out.println(annotation);
}
System.out.println("------------------------------------");
//方法获取不到@Override注解
Method method = MessageImpl.class.getDeclaredMethod("send", String.class);
Annotation[] annotationsT = method.getAnnotations();
for (Annotation annotation : annotationsT) {
System.out.println(annotation);
}
}
}
@FunctionalInterface
@Deprecated(since = "3.0")
interface IMessage {
/**
* 输出数据
*
* @param msg 传递的数据
*/
void send(String msg);
}
@Deprecated(since = "1.7")
class MessageImpl implements IMessage {
@Override
@Deprecated(since = "1.5")
public void send(String msg) {
System.out.println(msg);
}
}
class Factory {
private Factory() {
}
@SuppressWarnings("unchecked")
public static <T> T getInstance(String classValue) {
Object object = null;
try {
Class<?> clazz = Class.forName(classValue);
object = clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
return null;
}
return (T) object;
}
}
结果:
www.baidu.com
------------------------------------
@java.lang.FunctionalInterface()
@java.lang.Deprecated(forRemoval=false, since="3.0")
------------------------------------
@java.lang.Deprecated(forRemoval=false, since="1.7")
------------------------------------
@java.lang.Deprecated(forRemoval=false, since="1.5")
自定义Annotation
可以自己生成一个注解进行操作。
@Retention:
1、SOURCE:在源代码编写过程中生效。
2、CLASS:再类定义时生效。
3、RUNTIME:在类执行的时候生效。
@Target:
1、ANNOTATION_TYPE:只能够出现在注解定义的操作上。
2、METHOD:只能出现在方法上。
3、FIELD:只能出现在成员属性上。
4、TYPE:只能出现在类结构上。
5、PARAMETER:只能狗出现在参数上。
示例:
public class AnnotationTest {
public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
Class<?> clazz = Message.class;
Method method = clazz.getDeclaredMethod("send");
Field field = clazz.getDeclaredField("name");
Annotation[] methodAnnotations = method.getAnnotations();
Annotation[] fieldAnnotations = field.getAnnotations();
for (Object annotation : fieldAnnotations) {
System.out.println("FIELD:"+annotation);
}
System.out.println("--------------------------------------");
for (Object annotation : methodAnnotations) {
System.out.println("METHOD:"+annotation);
}
}
}
//设置注解可以用到得范围(成员属性和方法)
@Target({ElementType.FIELD, ElementType.METHOD})
//设置运行范围
@Retention(RetentionPolicy.RUNTIME)
@interface Action {
String title() default "Hello World!!!"; //设置默认值
String value();
}
class Message {
@Action("tan") //value可以直接赋值
private String name;
@Action("tan")
public void send() {
}
}
结果:
FIELD:@com.tx.test.annotation.Action(title="Hello World!!!", value="tan")
--------------------------------------
METHOD:@com.tx.test.annotation.Action(title="Hello World!!!", value="tan")
Annotation和动态工厂模式
使用注解可以根据注解的值进行实例化操作,完全解耦。
package com.tx.test.factoryannotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class TestFactoryAnnotation {
public static void main(String[] args) throws Exception{
new Message().send("www.baidu.com");
}
}
@Target(ElementType.TYPE) //在类中都有效
@Retention(RetentionPolicy.RUNTIME)
@interface Action {
String value();
}
@Target(ElementType.CONSTRUCTOR) //在构造中有效
@Retention(RetentionPolicy.RUNTIME)
@interface ConstructorValue {
String value();
}
interface IMessage extends AutoCloseable {
/**
* 建立通讯连接
*
* @return 返回boolean值
*/
boolean build();
}
class InternetMessage implements IMessage {
@Override
public boolean build() {
System.out.println("【InternetMessage】互联网通讯连接。。。");
return true;
}
@Override
public void close() throws Exception {
System.out.println("【InternetMessage】互联网通讯关闭。。。");
}
}
class RadioMessage implements IMessage {
@Override
public boolean build() {
System.out.println("【RadioMessage】无线通讯连接。。。");
return true;
}
@Override
public void close() throws Exception {
System.out.println("【InternetMessage】无线电通讯关闭。。。");
}
}
class Factory {
private Factory() {
}
@SuppressWarnings("unchecked cast")
public static <T> T getInstance(String kindName) {
try {
return (T) Class.forName(kindName).getDeclaredConstructor().newInstance();
} catch (Exception e) {
return null;
}
}
}
@Action("com.tx.test.factoryannotation.RadioMessage")
class Message{
private IMessage message;
@ConstructorValue("com.tx.test.factoryannotation.Factory")
public Message(){
try{
String actionValue = this.getClass().getAnnotation(Action.class).value();
String constructorValue = this.getClass().getConstructor().getAnnotation(ConstructorValue.class).value();
this.message = (IMessage) Class.forName(constructorValue).getMethod("getInstance",String.class).invoke(null,actionValue);
}catch (Exception e){
e.printStackTrace();
}
}
public void send(String msg) throws Exception {
if(this.message.build()){
System.out.println("【消息发送】"+msg);
this.message.close();
}
}
}
结果:
【RadioMessage】无线通讯连接。。。
【消息发送】www.baidu.com
【InternetMessage】无线电通讯关闭。。。
只需要将Action的位置换成另一个子类,就可以直接调用累一个类的build和close的方法。
当@Action("com.tx.test.factoryannotation.InternetMessage")
//结果
【InternetMessage】互联网通讯连接。。。
【消息发送】www.baidu.com
【InternetMessage】互联网通讯关闭。。。