JDK1.5之后,Java开发提供了Annotation技术支持。
反射取得Annotation信息
进行类或方法的定义时,都可以通过Annotation进行声明,如果想要获取Annotation的信息,可以直接通过反射完成。在java.lang.reflect中AccessibleObject类提供有获取Annotation类的方法。
(AccessibleObject是Constructor,Method,Field的父类)
AccessibleObject的方法:
- 获取全部Annotation:
public Annotation[] getAnnotations()
- 获取指定的Annotation:
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
Annotation是一个接口jdk1.5。
package wzr.study10.reflex.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
public class AnnotationTest {
public static void main(String[] args) throws Exception {
Method meth=Message.class.getMethod("send", String.class);
DefaultAnnotation anno=meth.getAnnotation(DefaultAnnotation.class);
String msg=anno.title()+"("+anno.url()+")";
meth.invoke(Message.class.getDeclaredConstructor().newInstance(), msg);
}
}
@Retention(RetentionPolicy.RUNTIME)//调用Annotation的运行策略
@interface DefaultAnnotation{//自定义Annotation
public String title();//获取数据
public String url() default "www.study.amazing";//获取数据,默认值
}
class Message{
@DefaultAnnotation(title="look")
public void send(String msg) {
System.out.println("send message:"+msg);
}
}
使用Annotation最大的优点是可以结合反射,实现程序的处理。
工程设计模式与Annotation整合
以Annotation的作用,可以在开发中做什么事情?
结合工厂设计模式应用Annotation操作
(特征:利用注解操作程序的执行)
package wzr.study10.reflex.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class FactoryTest {
public static void main(String[] args) {
MessageService msg=new MessageService();
msg.send("MessageService:Factory:FactoryProxy:Message");
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MessageUse{
public Class<?> cla();
}
@MessageUse(cla=MessageImpl.class)//利用Annotation实现了类的使用
class MessageService{
private IMessage msg;
public MessageService() {
MessageUse use=MessageService.class.getAnnotation(MessageUse.class);
this.msg=Factory.newInstance(use.cla());
// Class<?> instance=use.cla();
// this.msg=(IMessage)Factory.newInstance(instance);
// 教学视频着实有把我恶新了一次,不行了
}
public void send(String msg) {
this.msg.send(msg);
}
}//写这个类的时候心里深深的感到枯燥的东西的恶心,快吐了
class Factory{
private Factory() {}
public static <T> T newInstance(Class<?> cla) {
try {
return (T)new FactoryProxy().bind(cla.getDeclaredConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
class FactoryProxy implements InvocationHandler{
private Object target=null;
public Object bind(Object target) {
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public boolean connect() {
System.out.println("[代理]建立连接");
return true;
}
public void close() {
System.out.println("【代理】关闭连接");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if(this.connect()) {
return method.invoke(target, args);
}
return null;
}catch(Exception e) {
throw new Exception("【代理】消息无法发送");
}finally {
this.close();
}
}
}
interface IMessage{
public void send(String msg);
}
class MessageImpl implements IMessage{
@Override
public void send(String msg) {
// TODO Auto-generated method stub
System.out.println("send message:"+msg);
}
}
谁要是敢说这种使用方式简洁,我当场疯掉,只有空框架的感觉太痛苦了!!!
唯一一点,Annotation可用在代码赋值传递中,发现了赋值新大陆!!!