您的位置:首页 > 编程语言 > Java开发

疯狂JAVA讲义---第十四章:Annotation(注释)

2009-01-23 23:13 381 查看
从JDK1.5开始,java增加了对元数据的支持,既Annotation,也就是代码中的特殊标记。

先说下3个基本的系统Annotation

@Override:限定重写父类

@Deprecated:标记已过时

@SuppressWarning:抑制编译器警告

下面分别举个例子

eg:@Override

public class Fruit
{
public void info()
{
System.out.println("水果的info方法。。。");
}
}

class Apple extends Fruit
{
//使用@Override指定下面方法必须重写父类方法
@Override
//	public void info()
public void inf0()
{
System.out.println("苹果重写水果的info方法。。。");
}
}


eg:@Deprecated

class Apple
{
//定义info方法已过时
@Deprecated
public void info()
{
System.out.println("Apple的info方法");
}
}
public class DeprecatedTest
{
public static void main(String[] args)
{
//下面使用info方法时将会被编译器警告
new Apple().info();
}
}


eg:@SuppressWarning

@SuppressWarnings(value="unchecked")
public class SuppressWarningsTest
{
public static void main(String[] args)
{
List<String> myList = new ArrayList();
}
}


然后说下自定义annotation:

定义也很方便用@interface关键字,eg

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EJBServicePrompt {
String[] params() default "unknown";
}


@Retention(RetentionPolicy.RUNTIME)

表示运行时保留annotation
@Target(ElementType.METHOD)

表示保留方法的annotation

annotation分类

1.没有成员定义的annotation称为 标记 定义eg

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//定义一个标记注释,不包含任何成员变量,即不可传入元数据
public @interface Testable
{
}


junit中就用到了以上定义来表示方法可测试

下面看是程序是如何得到annotation的,eg

public class TestProcessor
{
public static void process(String clazz)
throws ClassNotFoundException
{
int passed = 0;
int failed = 0;
//遍历obj对象的所有方法
for (Method m : Class.forName(clazz).getMethods())
{
//如果包含@Testable标记注释
if (m.isAnnotationPresent(Testable.class))
{
try
{
//调用m方法
m.invoke(null);
//passed加1
passed++;
}
catch (Exception ex)
{
System.out.printf("方法" + m + "运行失败,异常:" + ex.getCause() + "/n");
failed++;
}
}
}
//统计测试结果
System.out.printf("共运行了:" + (passed + failed)+ "个方法,其中:/n" +
"失败了:" + failed + "个,/n" +
"成功了:" + passed + "个!/n");
}
}


 

2.有成员定义的annotation称为 元数据 eg:(这个程序实现了用Annotation简化事件编程)

定义:

@Target(ElementType.FIELD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface ActionListenerFor
{
//定义一个成员变量,用于设置元数据
//该listener成员变量用于保存监听器实现类
String listener();
}


标记下:

 
public class AnnotationTest
{
private JFrame mainWin = new JFrame("使用注释绑定事件监听器");
//使用注释为ok按钮绑定事件监听器
@ActionListenerFor(listener="OkListener")
private JButton ok = new JButton("确定");
//使用注释为cancel按钮绑定事件监听器
@ActionListenerFor(listener="CancelListener")
private JButton cancel = new JButton("取消");

public void init()
{
//初始化界面的方法
JPanel jp = new JPanel();
jp.add(ok);
jp.add(cancel);
mainWin.add(jp);
ActionListenerInstaller.processAnnotations(this);
mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWin.pack();
mainWin.setVisible(true);
}
public static void main(String[] args)
{
new AnnotationTest().init();
}

}
class OkListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
JOptionPane.showMessageDialog(null , "单击了确认按钮");
}
}
class CancelListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
JOptionPane.showMessageDialog(null , "单击了取消按钮");
}
}


实现绑定:

public class ActionListenerInstaller
{
//处理注释的方法,其中obj是包含注释的对象
public static void processAnnotations(Object obj)
{
try
{
//获取obj对象的类
Class cl = obj.getClass();
//获取指定obj对象的所有Field,并遍历每个Field
for (Field f : cl.getDeclaredFields())
{
//将指定Field设置成可自由访问的,避免private的Field不可访问
f.setAccessible(true);
//获取指定Field的、ActionListenerFor类型的注释
ActionListenerFor a = f.getAnnotation(ActionListenerFor.class);
if (a != null && a instanceof AbstractButton)
{
//获取a注释里的元数据listner(它是一个监听器类)
Class listenerClazz = Class.forName(a.listener());
//使用反射来创建listner类的对象
ActionListener al = (ActionListener)listenerClazz.newInstance();
//获取f Field实际对应的对象
AbstractButton ab = (AbstractButton )f.get(obj);
//为ab对象添加事件监听器
ab.addActionListener(al);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息