JavaSE学习笔记--Item1 注解Annotation_@item注解

  • Annotation[] getAnnotations():得到所有的注解类型
  • Annotation[] getDeclaredAnnotations():得到自己上面的直接的注解类型
  • boolean isAnnotationPresent(Class clazz):有没有指定的注解

Class、Method、Field、Constructor等都实现了该接口。
实例:编写一个自己的注解Anno1,在MyClass1中使用该注解,MyClass2继承MyClass1,这样,MyClass2也具有MyClass1上的注解,但是两者还是有差别的,看如下代码

package com.itheima.other.metaanno;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
@Inherited
public @interface Anno1 {

}

MyClass1

package com.itheima.other.metaanno;
/\*\*
 \* 这是一个测试类
 \* @author wzhting
 \*
 \*/
@Anno1
public class MyClass1 {

}

MyClass2

package com.itheima.other.metaanno;

import java.lang.annotation.Annotation;

public class MyClass2 extends MyClass1 {
    public static void main(String[] args) {
        Class clazz = MyClass2.class;
// Anno1 a1 = (Anno1) clazz.getAnnotation(Anno1.class);
// System.out.println(a1);

        Annotation ans[]  =  clazz.getDeclaredAnnotations();//获取直接存在的注解
        for(Annotation a:ans)
            System.out.println(a);
    }
}

比如:判断Object这个类上面有没有MyAnn1的注解

Class clazz = Object.class;
Boolean b = clazz.isAnnotationPresent(MyAnn1.class);
2、注解的生命周期:

2.1 AnnotatedElement元注解

只能用在注解上的注解,就是元注解。JDK中定义了如下元Annotation:

  • @Retention:

@Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留的, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 通过这个变量指定域。

  1. RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解. 这是默认值
  2. RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以通过反射获取该注释
  3. RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释

这里写图片描述

  • @Target:指示注解能用在何处
    ElementType:指定注解用于修饰类的哪个成员. @Target 包含了一个名为 value,类型为ElementType的成员变量。看源码可知有TYPE (Class,Interface), FIELD, METHOD, PARAMETER, ANNOTATION_TYPE等声明常量。

实例:自定义注解类MyTest

首先定义两个实体类,用于单元测试分别为PersonDaoImpl 和测试类PersonDaoImplTest
PersonDaoImpl

package com.itheima.dao.impl;

public class PersonDaoImpl {
    public void add(){
        System.out.println("保存了");
    }
    public void del(){
        System.out.println("执行了删除");
    }
}

PersonDaoImplTest

package com.itheima.dao.impl;

import org.junit.Test;

public class PersonDaoImplTest {
    private PersonDaoImpl dao = new PersonDaoImpl();

    //测试方法:必须是public的;没有返回值;没有参数
    @MyTest(timeout=1)//===>自己编写MyTest注解
    public void testAdd() throws InterruptedException{
// Thread.sleep(100);
        dao.add();
    }
    public void testDel(){
        dao.del();
    }
}

自定义一个类MyTest,和JUnit的@Test类相似。

package com.itheima.dao.impl;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)//编译时,JVM保留注解
@Target(ElementType.METHOD)//使用于方法。

public @interface MyTest {
    long timeout() default -1;//没有时间限制。单位是毫秒
}

反射注解的方法及属性(重点)
通过反射技术,编写MyTestRunner 类,实现MyTest注解的功能。

package com.itheima.dao.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyTestRunner {

    public static void main(String[] args) throws Exception{
        test1();
    }
    //反射注解的属性
    private static void test2() throws IllegalAccessException,
            InvocationTargetException, InstantiationException {
        Class clazz = PersonDaoImplTest.class;
        Method ms[] = clazz.getMethods();
        for(Method m:ms){
            MyTest myTest = m.getAnnotation(MyTest.class);//如果当前方法上面没有@MyTest注解,返回的是null
            if(myTest!=null){
                //执行该方法,判断是否超时
                long time = System.currentTimeMillis();
                m.invoke(clazz.newInstance(), null);
                long actualUseTime = System.currentTimeMillis()-time;//实际耗时
                //获取注解上配置的timeout属性的值
                long planUserTime = myTest.timeout();
                if(planUserTime>=0){
                    //说明用户指定了时间
                    if(actualUseTime>planUserTime)
                        throw new RuntimeException("超时");
                }
            }
        }
    }
    //反射方法上面的注解

    private static void test1() throws IllegalAccessException,
            InvocationTargetException, InstantiationException {
        //得到测试类的字节码
        Class clazz = PersonDaoImplTest.class;
        //得到所有的方法
        Method ms[] = clazz.getMethods();
        //判断方法上面有没有叫做@MyTest的注解
        for(Method m:ms){
            boolean b = m.isAnnotationPresent(MyTest.class);
            System.out.println(m.getName()+":"+b);
        //如果有:调用该方法
            if(b)
                m.invoke(clazz.newInstance(), null);
        }
    }

/\* testAdd:true
 testDel:false
 wait:false
 wait:false
 wait:false
 equals:false
 toString:false
 hashCode:false
 getClass:false
 notify:false
 notifyAll:false\*/

}

以下两个了解即可。

  • @Documented:用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
  • @Inherited:被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解

三、servlet3.0 中的注解

在servlet3.0以后,就可以采用注解的方式取代web.xml文件里的servlet映射了
比如如下servlet

package com.itheima.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
### 自学几个月前端,为什么感觉什么都没学到??

----------------------------------------------------------------------------------

这种现象在很多的初学者和自学前端的同学中是比较的常见的。

因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。

最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。

很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。



这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。

但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。



![](https://img-blog.csdnimg.cn/img_convert/15be8206a9f6e5bd9e8e930303b613ee.png)



还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。



所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值