【Java基础】注解、类加载器的使用

2018-10-02  本文已影响0人  灰色孤星

源代码:https://gitee.com/AgentXiao/annotation

一、说明

它不是注释 注释是程序员写的,给程序员的
注解给程序看,用于描述程序如何运行及在什么阶段来运行。
注解现在在实际开发中,最大的功能是用于替换配置文件。
注解是jdk1.5的新特性
可以通过反射来让注解具有功能。
注解 @xxxx

二、自定义注解

1、JDK中的三种基本注解

a、@Override 检查子类确实是覆盖了父类的方法。
b、@Deprecated:说明已经过时了。
c、@SuppressWarnings({ "unused", "deprecation" }):抑制程序中的警告。unused警告的类型。{}数组。all抑制所有警告。

2、自定义注解

声明一个注解

public @interface MyAnnotation{}

注解的本质就是一个接口,这个接口需要继承 Annotation接口。但是不能人为进行继承。反编译后得到一下信息:public interface MyAnnotation extends java.lang.annotation.Annotation。
注解中的成员
注解本质上就是接口,接口中可以有属性方法
属性 : 例:int age();
注解的定义者

/**
 * @InterfaceName MyAnnotation
 * @Description 自定义注解类
 * @Author xwd
 * @Date 2018/10/2 10:28
 */
public @interface MyAnnotation {
    //属性
    int age();
    String name();
    //有默认值,在使用时给不给值都可以
    String sex() default "";
}

注解的使用者

/**
 * @ClassName TestMyAnno
 * @Description 测试我自定义的注解类
 * @Author xwd
 * @Date 2018/10/2 10:40
 */
public class TestMyAnno {
    @MyAnnotation(age = 18,name = "xwd")
    public void test(){

    }
}

3、注解的反射(重点)

a、反射注解类
java.lang.reflect.AnnotatedElement

/**
 * @InterfaceName MyTest
 * @Description 自定义的测试注解
 * @Author xwd
 * @Date 2018/10/2 15:11
 */
public @interface MyTest {
    
}

如下图在使用自定义的测试注解时,是不会出现可执行标记的。

使用自定义注解

我们写一个类进行测试,实现如果该方法被@MyTest注解了,就输出true且执行。

package pri.xiaowd.demo05;

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

/**
 * @ClassName TestRunner
 * @Description
 * @Author xwd
 * @Date 2018/10/2 15:19
 */
public class TestRunner {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        //实现查看测试类中的方法,哪个有@MyTest就执行那个

        //得到class对象
        Class c = Student.class;
        //得到类中的方法
        Method[] methods = c.getMethods();
        //遍历所有方法
        for(Method method:methods){
            //如果这个方法有@MyTest注解,则执行
            boolean b = method.isAnnotationPresent(MyTest.class);
            System.out.println(method.getName()+"-->"+b);
            if(b){
                method.invoke(c.newInstance(),null);
            }
        }
    }
}

输出结果发现:
eatLunch-->false
readBook-->false
这是因为自定义注解@MyTest的生命周期默认为CLASS。在讲解之前,先说“元注解”的概念。

生命周期

在我们运行程序时,是通过类加载器在内存中获取注解的,但是这是自定义注解的生命周期已死亡,因此也是取不到的。
什么是元注解
只能用在注解上的注解叫做元注解。(即:用于修饰注解的注解)

/**
 * @InterfaceName MyTest
 * @Description 自定义的测试注解
 * @Author xwd
 * @Date 2018/10/2 15:11
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {

}

接了一个元注解之后,运行得:
readBook-->true
在看书
eatLunch-->false

4、Servlet3.0:web.xml已经不是必须的了。替代它的就是注解。

例如servlet中使用@webServlet(name = "LoginServlet",urlPattern = "/LoginServlet")
例如Filter中使用@webFilter("/*")
使用web.xml:优点可配置,不用修改源码;缺点是不直观,开发效率低。
使用注解:有点是直观,开发效率高;缺点是硬编码

三、类加载器

1、作用:负责把磁盘上的class文件加载到JVM中,并生成Class对象

2、JVM中的类加载器:

3、父类委托机制

父类委托机制

如果需要加载一个类,由于父类委托机制,最顶层的父类BootStrap会先查找,如果找不到ExtClassLoader查找,还是找不到AppClassLoader进行查找,再找不到抛异常。

上一篇 下一篇

猜你喜欢

热点阅读