HOME 首页
SERVICE 服务产品
XINMEITI 新媒体代运营
CASE 服务案例
NEWS 热点资讯
ABOUT 关于我们
CONTACT 联系我们
创意岭
让品牌有温度、有情感
专注品牌策划15年

    Java什么是注解

    发布时间:2023-04-03 18:15:25     稿源: 创意岭    阅读: 69        当前文章关键词排名出租

    大家好!今天让创意岭的小编来大家介绍下关于Java什么是注解的问题,以下是小编对此问题的归纳整理,让我们一起来看看吧。

    开始之前先推荐一个非常厉害的Ai人工智能工具,一键生成原创文章、方案、文案、工作计划、工作报告、论文、代码、作文、做题和对话答疑等等

    只需要输入关键词,就能返回你想要的内容,越精准,写出的就越详细,有微信小程序端、在线网页版、PC客户端

    官网:https://ai.de1919.com,如需相关业务请拨打电话175-8598-2043,或添加微信:1454722008

    本文目录:

    Java什么是注解

    一、java注解开发是什么?是不是不用在xml里配置ssh?以前都是配置xml,注解让我晕了

    注解(Annotation )就是将一些标注的信息,写在java文件中,实际上servlet以前在web.xml中注册(配置mapping等等),现在servlet也可以采用注解的方式,将配置直接写在servlet类之上。采用注解的好处就是:不需要单独一个一个的在外部文件中增加配置信息了,如果采用注解方式,当你写完一个类(包括注解部分),那个这个类的配置也就写完了,不需要反复于配置文件和类的编写。采用注解的坏处是:1、让一些配置信息写在java代码中,导致代码比较混乱,2、有源码还好,如果没源代码呢?因为注解是写在java文件中的,所以如果给你的项目是通过注解实现的,而且给你的项目不是源码,那么你是没有办法修改配置信息的,除非反编译。

    对于hibernate我个人觉得采用注解的方式要比采用xml的方式好(个人认为),即省了一大堆的mapping文件,又提高了效率,而且采用的注解是JPA提供的,可以跨ORM框架。

    Struts2而言还是要掌握xml配置方式,因为xml配置反而效率高,因为可以用通配符之类的,比较灵活,有时设计的好,配一次就够了。

    Spring要把xml和注解方式结合起来最好。对于IOC方面通过注解比较方便,而对于AOP方面,通过xml比较方便。所以学习时要有主次之分。

    二、java注解有什么用

    注解常见的作用有以下几种:

    1.生成文档。这是最常见的,也是java 最早提供的注解,常用的有@param @return 等;

    2.跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置,作用就是减少配置,现在的框架基本都使用了这种配置来减少配置文件的数量;

    3.在编译时进行格式检查。如@Override放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。

    三、JAVA程序中注释的作用及类型分别是什么?

    对于Java注释我们主要了解三种:

    1, // 注释一行  

    2, /* ...... */ 注释若干行

    3, /**……*/文档注释  /** ...... */ 注释若干行,并写入 javadoc文档

    java图标通常这种注释的多行写法如下: /** * ......... * ......... */

    Java:

    Java什么是注解

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

    Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。

    四、java注解的类型可以是哪些

    使用注解

    在一般的Java开发中,最常接触到的可能就是@Override和@SupressWarnings这两个注解了。使用@Override的时候只需要一个简单的声明即可。这种称为标记注解(marker annotation ),它的出现就代表了某种配置语义。而其它的注解是可以有自己的配置参数的。配置参数以名值对的方式出现。使用 @SupressWarnings的时候需要类似@SupressWarnings({"uncheck", "unused"})这样的语法。在括号里面的是该注解可供配置的值。由于这个注解只有一个配置参数,该参数的名称默认为value,并且可以省略。而花括号则表示是数组类型。在JPA中的@Table注解使用类似@Table(name = "Customer", schema = "APP")这样的语法。从这里可以看到名值对的用法。在使用注解时候的配置参数的值必须是编译时刻的常量。

    从某种角度来说,可以把注解看成是一个XML元素,该元素可以有不同的预定义的属性。而属性的值是可以在声明该元素的时候自行指定的。在代码中使用注解,就相当于把一部分元数据从XML文件移到了代码本身之中,在一个地方管理和维护。

    开发注解

    在一般的开发中,只需要通过阅读相关的API文档来了解每个注解的配置参数的含义,并在代码中正确使用即可。在有些情况下,可能会需要开发自己的注解。这在库的开发中比较常见。注解的定义有点类似接口。下面的代码给出了一个简单的描述代码分工安排的注解。通过该注解可以在源代码中记录每个类或接口的分工和进度情况。

    @Retention(RetentionPolicy.RUNTIME)

    @Target(ElementType.TYPE)

    public @interface Assignment {

        String assignee();

        int effort();

        double finished() default 0;

    }

    @interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。可以通过default来声明参数的默认值。在这里可以看到@Retention和@Target这样的元注解,用来声明注解本身的行为。@Retention用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种,分别表示注解保存在类文件、JVM运行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。@Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。

    处理注解

    在程序中添加的注解,可以在编译时刻或是运行时刻来进行处理。在编译时刻处理的时候,是分成多趟来进行的。如果在某趟处理中产生了新的Java源文件,那么就需要另外一趟处理来处理新生成的源文件。如此往复,直到没有新文件被生成为止。在完成处理之后,再对Java代码进行编译。JDK 5中提供了apt工具用来对注解进行处理。apt是一个命令行工具,与之配套的还有一套用来描述程序语义结构的Mirror API。Mirror API(com.sun.mirror.*)描述的是程序在编译时刻的静态结构。通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供相应的处理逻辑。具体的处理工作交给apt工具来完成。编写注解处理器的核心是AnnotationProcessorFactory和AnnotationProcessor两个接口。后者表示的是注解处理器,而前者则是为某些注解类型创建注解处理器的工厂。

    以上面的注解Assignment为例,当每个开发人员都在源代码中更新进度的话,就可以通过一个注解处理器来生成一个项目整体进度的报告。 首先是注解处理器工厂的实现。

    public class AssignmentApf implements AnnotationProcessorFactory {  

        public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds,? AnnotationProcessorEnvironment env) {

            if (atds.isEmpty()) {

               return AnnotationProcessors.NO_OP;

            }

            return new AssignmentAp(env); //返回注解处理器

        } 

        public Collection<String> supportedAnnotationTypes() {

            return Collections.unmodifiableList(Arrays.asList("annotation.Assignment"));

        }

        public Collection<String> supportedOptions() {

            return Collections.emptySet();

        }

    }

    AnnotationProcessorFactory接口有三个方法:getProcessorFor是根据注解的类型来返回特定的注解处理器;supportedAnnotationTypes是返回该工厂生成的注解处理器所能支持的注解类型;supportedOptions用来表示所支持的附加选项。在运行apt命令行工具的时候,可以通过-A来传递额外的参数给注解处理器,如-Averbose=true。当工厂通过 supportedOptions方法声明了所能识别的附加选项之后,注解处理器就可以在运行时刻通过AnnotationProcessorEnvironment的getOptions方法获取到选项的实际值。注解处理器本身的基本实现如下所示。

    public class AssignmentAp implements AnnotationProcessor { 

        private AnnotationProcessorEnvironment env;

        private AnnotationTypeDeclaration assignmentDeclaration;

        public AssignmentAp(AnnotationProcessorEnvironment env) {

            this.env = env;

            assignmentDeclaration = (AnnotationTypeDeclaration) env.getTypeDeclaration("annotation.Assignment");

        }

        public void process() {

            Collection<Declaration> declarations = env.getDeclarationsAnnotatedWith(assignmentDeclaration);

            for (Declaration declaration : declarations) {

               processAssignmentAnnotations(declaration);

            }

        }

        private void processAssignmentAnnotations(Declaration declaration) {

            Collection<AnnotationMirror> annotations = declaration.getAnnotationMirrors();

            for (AnnotationMirror mirror : annotations) {

                if (mirror.getAnnotationType().getDeclaration().equals(assignmentDeclaration)) {

                    Map<AnnotationTypeElementDeclaration, AnnotationValue> values = mirror.getElementValues();

                    String assignee = (String) getAnnotationValue(values, "assignee"); //获取注解的值

                }

            }

        }   

    }

    注解处理器的处理逻辑都在process方法中完成。通过一个声明(Declaration)的getAnnotationMirrors方法就可以获取到该声明上所添加的注解的实际值。得到这些值之后,处理起来就不难了。

    在创建好注解处理器之后,就可以通过apt命令行工具来对源代码中的注解进行处理。 命令的运行格式是apt -classpath bin -factory annotation.apt.AssignmentApf src/annotation/work/*.java,即通过-factory来指定注解处理器工厂类的名称。实际上,apt工具在完成处理之后,会自动调用javac来编译处理完成后的源代码。

    JDK 5中的apt工具的不足之处在于它是Oracle提供的私有实现。在JDK 6中,通过JSR 269把自定义注解处理器这一功能进行了规范化,有了新的javax.annotation.processing这个新的API。对Mirror API也进行了更新,形成了新的javax.lang.model包。注解处理器的使用也进行了简化,不需要再单独运行apt这样的命令行工具,Java编译器本身就可以完成对注解的处理。对于同样的功能,如果用JSR 269的做法,只需要一个类就可以了。

    @SupportedSourceVersion(SourceVersion.RELEASE_6)

    @SupportedAnnotationTypes("annotation.Assignment")

    public class AssignmentProcess extends AbstractProcessor {

        private TypeElement assignmentElement; 

        public synchronized void init(ProcessingEnvironment processingEnv) {

            super.init(processingEnv);

            Elements elementUtils = processingEnv.getElementUtils();

            assignmentElement = elementUtils.getTypeElement("annotation.Assignment");

        } 

        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

            Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(assignmentElement);

            for (Element element : elements) {

                processAssignment(element);

            }

        }

        private void processAssignment(Element element) {

            List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();

            for (AnnotationMirror mirror : annotations) {

                if (mirror.getAnnotationType().asElement().equals(assignmentElement)) {

                    Map<? extends ExecutableElement, ? extends AnnotationValue> values = mirror.getElementValues();

                    String assignee = (String) getAnnotationValue(values, "assignee"); //获取注解的值

                }

            }

        } 

    }

    仔细比较上面两段代码,可以发现它们的基本结构是类似的。不同之处在于JDK 6中通过元注解@SupportedAnnotationTypes来声明所支持的注解类型。另外描述程序静态结构的javax.lang.model包使用了不同的类型名称。使用的时候也更加简单,只需要通过javac -processor annotation.pap.AssignmentProcess Demo1.java这样的方式即可。

    上面介绍的这两种做法都是在编译时刻进行处理的。而有些时候则需要在运行时刻来完成对注解的处理。这个时候就需要用到Java的反射API。反射API提供了在运行时刻读取注解信息的支持。不过前提是注解的保留策略声明的是运行时。Java反射API的AnnotatedElement接口提供了获取类、方法和域上的注解的实用方法。比如获取到一个Class类对象之后,通过getAnnotation方法就可以获取到该类上添加的指定注解类型的注解。

    实例分析

    下面通过一个具体的实例来分析说明在实践中如何来使用和处理注解。假定有一个公司的雇员信息系统,从访问控制的角度出发,对雇员的工资的更新只能由具有特定角色的用户才能完成。考虑到访问控制需求的普遍性,可以定义一个注解来让开发人员方便的在代码中声明访问控制权限。

    @Retention(RetentionPolicy.RUNTIME)

    @Target(ElementType.METHOD)

    public @interface RequiredRoles {

        String[] value();

    }

    下一步则是如何对注解进行处理,这里使用的Java的反射API并结合动态代理。下面是动态代理中的InvocationHandler接口的实现。

    public class AccessInvocationHandler<T> implements InvocationHandler {

        final T accessObj;

        public AccessInvocationHandler(T accessObj) {

            this.accessObj = accessObj;

        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            RequiredRoles annotation = method.getAnnotation(RequiredRoles.class); //通过反射API获取注解

            if (annotation != null) {

                String[] roles = annotation.value();

                String role = AccessControl.getCurrentRole();

                if (!Arrays.asList(roles).contains(role)) {

                    throw new AccessControlException("The user is not allowed to invoke this method.");

                }

            }

            return method.invoke(accessObj, args);

        } 

    }

    在具体使用的时候,首先要通过Proxy.newProxyInstance方法创建一个EmployeeGateway的接口的代理类,使用该代理类来完成实际的操作。

    以上就是关于Java什么是注解相关问题的回答。希望能帮到你,如有更多相关问题,您也可以联系我们的客服进行咨询,客服也会为您讲解更多精彩的知识和内容。


    推荐阅读:

    基于javaweb的图书管理系统(基于javaweb的图书管理系统论文)

    java可变参数是什么(java可变参数怎么用)

    杭州Java研发岗位薪资范围(杭州java研发岗位薪资范围是多少)

    海外视频APP(海外视频素材网站)

    竞价投放策略(竞价投放策略有哪些)