当前位置: 首页 > news >正文

免费网站建设视频代发新闻稿最大平台

免费网站建设视频,代发新闻稿最大平台,商务网站b2b,用html做的网站步骤前言:注解目前非常的流行,很多主流框架都支持注解,特别是在Java SSM框架之中存在各种注解,因为后续会学习这几个框架,所有需要先将这几个框架中要用到的知识点反射机制和注解先学习一下。日常项目中我们也可以用到注解…

前言:注解目前非常的流行,很多主流框架都支持注解,特别是在Java SSM框架之中存在各种注解,因为后续会学习这几个框架,所有需要先将这几个框架中要用到的知识点反射机制和注解先学习一下。日常项目中我们也可以用到注解,编写代码更简洁高效。

一、注解的概念

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

1、从JDK5.0始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的。可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解,开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息(Spring的AOP面向切面编程)。

值得注意的是,注解不是代码本身的一部分。注解对于代码的运行效果没有直接影响,同样无法改变代码本身,注解主要给编译器及工具类型的软件用的。注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。

2、注解的使用场景

Java 官方文档写明:

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。注解主要针对的是编译器和其它工具软件(SoftWare tool)使用的。

注解有许多用处,主要如下:

a、提供信息给编译器: 编译器可以利用注解来探测错误和警告信息

b、编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。

c、运行时的处理: 某些注解可以在程序运行的时候接受代码的提取,借助反射手段

当开发者使用了Annotation 修饰了类、方法、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。

3、其实在前面我用最基础的Servlet写APP服务端时,就接触过servlet3.0中就引入的@WebServlet ——该注解用来声明一个Servlet的注册配置,用来映射客户端Http访问路径和Servlet。使用该注解后就不需要在Dynamic Web project中传统的web.xml中注册声明麻烦的  <servlet-name>和  <servlet-mapping>配置,这样编写代码简单方便太多了。

有了@WebServlet注解,就不用配置如下图的web.xml,相当于上面注解官方文档所说的注解用处b:软件工具可以用来利用注解信息来生成类似web/xml的配置信息,解放了程序猿。

二、Java内置注解

注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。

1、作用在代码的注解,位于java.lang中

Java 5.0内置了3种标准注解:

  • @Override,表示当前的方法定义将覆盖超类中的方法。

  • @Deprecated,标记被弃用的代码。

  • @SuppressWarnings,指示编译器去忽略所标注内容产生的警告

上面这三个注解或多或少我们都会在写代码的时候遇到。

2、作用在其他注解的注解(即元注解或基本注解),位于java.lang.annotation中

Java还提供了4种元注解,专门负责新注解的创建

简单解释:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

  • @Documented - 标记这些注解是否包含在用户文档中。

  • @Target - 标记这个注解应该是哪种 Java 成员。

3、从 Java 7 开始,额外添加了 3 个注解

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。函数式编程很火,所以 Java 8 也及时添加了这个特性。函数式接口 (Functional Interface) 就是一个具有一个方法的普通接口。

    我们进行线程开发中常用的 Runnable 就是一个典型的函数式接口,源码可以看到它就被 @FunctionalInterface 注解。

  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。(什么样的注解会多次应用呢?通常是注解的值可以同时取多个。)

三、自定义注解

注解的基本语法:创建如同接口,但是多了个 @ 符号。并且要想注解能够正常工作,定义注解的时候还需要用到元注解。

元注解......

public @interface 注解名 {定义体}

使用@interface自定义注解时,自动实现了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。实现了之后该自定义注解其实就相当于Java中的一个类。

1、自定义一个注解的方式

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)public @interface Test {}

我们观察上面自定义注解的创建代码,除了@符号,注解很像是一个接口,定义注解的时候必须用到元注解。

在注解中一般会有一些元素称为属性以表示某些值。注解的属性看起来就像接口的方法,唯一的区别在于可以为其制定默认值。没有元素的注解称为标记注解,上面的@Test就是一个标记注解。

2、注解的属性

注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

注解的可用的类型包括以下几种:所有基本类型、String、Class、enum、Annotation、以上类型的数组形式。元素不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation{int id();String msg();}

上面代码定义了 @TestAnnotation 这个注解中拥有 id 和 msg 两个属性。在使用的时候,我们应该给它们进行赋值。

赋值的方式是在注解使用时的括号内以 value="" 形式,多个属性之前用 ,隔开。注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略“value=”,直接写需要的值即可。

@TestAnnotation(id=3,msg="hello annotation")
public class Test {}

3、自定义注解总结

需要注意的是,使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个属性。方法的名称就是属性的名称,返回值类型就是属性的类型(返回值类型只能是8 种基本数据类型、Class、String、enum及它们的数组)。并且要想注解能够正常工作,定义注解的时候还需要用到元注解

定义注解格式:

        元注解.......

  public @interface 注解名 {定义体}

Annotation类型里面的属性该怎么设定: 

第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   4

第二,属性成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组。例如,String value();这里的参数成员就为String;  

第三,属性不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。

举个例子,下面看一个定义了属性的注解。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)public @interface UseCase {public String id();public String description() default "no description";}

定义了注解,必然要去使用注解。

 public class PasswordUtils {@UseCase(id = 47, description = "Passwords must contain at least one numeric")public boolean validatePassword(String password) {return (password.matches("\\w*\\d\\w*"));}@UseCase(id = 48)public String encryptPassword(String password) {return new StringBuilder(password).reverse().toString();}}

使用注解最主要的部分在于对注解的处理,那么就会涉及到注解处理器。

从原理上讲,注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解属性的值进行特定的处理。

public static void main(String[] args) {List<Integer> useCases = new ArrayList<Integer>();Collections.addAll(useCases, 47, 48, 49, 50);trackUseCases(useCases, PasswordUtils.class);}public static void trackUseCases(List<Integer> useCases, Class<?> cl) {for (Method m : cl.getDeclaredMethods()) {UseCase uc = m.getAnnotation(UseCase.class);if (uc != null) {System.out.println("Found Use Case:" + uc.id() + " "+ uc.description());useCases.remove(new Integer(uc.id()));}}for (int i : useCases) {System.out.println("Warning: Missing use case-" + i);}}

输出结果:

Found Use Case:47 Passwords must contain at least one numeric

Found Use Case:48 no description

Warning: Missing use case-49

Warning: Missing use case-50

四、注解通过反射提取

博文前面的部分讲了注解的基本语法,现在是时候检测我们所学的内容了。

要想在程序运行时正确检阅注解的内容信息,离不开一个手段,那就是反射。

1>首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}

2>然后通过 getAnnotation() 方法来获取 Annotation 对象。

public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}

 或者是 getAnnotations() 方法。

public Annotation[] getAnnotations() {}

注意:前一种方法返回指定类型的注解,后一种方法返回注解到这个元素上的所有注解。

如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了。

比如:

@TestAnnotation()
public class Test {public static void main(String[] args) {boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);if ( hasAnnotation ) {TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);System.out.println("id:"+testAnnotation.id());System.out.println("msg:"+testAnnotation.msg());}}}

程序的运行结果是:

id:-1
msg:

这个正是 TestAnnotation 中 id 和 msg 的默认值。

上面的例子中,只是检阅出了注解在类上的注解,其实属性、方法上的注解照样是可以的。同样还是要假手于反射。

@TestAnnotation(msg="hello")
public class Test {@Check(value="hi")int a;@Performpublic void testMethod(){}@SuppressWarnings("deprecation")public void test1(){Hero hero = new Hero();hero.say();hero.speak();}public static void main(String[] args) {boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);if ( hasAnnotation ) {TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);//获取类的注解System.out.println("id:"+testAnnotation.id());System.out.println("msg:"+testAnnotation.msg());}try {Field a = Test.class.getDeclaredField("a");a.setAccessible(true);//获取一个成员变量上的注解Check check = a.getAnnotation(Check.class);if ( check != null ) {System.out.println("check value:"+check.value());}Method testMethod = Test.class.getDeclaredMethod("testMethod");if ( testMethod != null ) {// 获取方法中的注解Annotation[] ans = testMethod.getAnnotations();for( int i = 0;i < ans.length;i++) {System.out.println("method testMethod annotation:"+ans[i].annotationType().getSimpleName());}}} catch (NoSuchFieldException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println(e.getMessage());} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println(e.getMessage());} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println(e.getMessage());}}}

它们的结果如下:

id:-1
msg:hello
check value:hi
method testMethod annotation:Perform

需要注意的是,如果一个注解要在运行时被成功提取,那么 @Retention(RetentionPolicy.RUNTIME) 是必须的。

五、Annotation 的作用

Annotation 是一个辅助类,它在 Junit、Struts、Spring 等工具框架中被广泛使用。

我们在编程中经常会使用到的 Annotation 作用有:

1)编译检查

Annotation 具有"让编译器进行编译检查的作用"。

例如,@SuppressWarnings, @Deprecated 和 @Override 都具有编译检查作用。

以@Override举例,某个方法被 @Override 的标注,则意味着该方法会覆盖父类中的同名方法。如果有方法被 @Override 标示,但父类中却没有"被 @Override 标注"的同名方法,则编译器会报错。示例如下:

上面是该程序在 eclipse 中的截图。从中,我们可以发现 "getString()" 函数会报错。这是因为 "getString() 被 @Override 所标注,但在OverrideTest 的任何父类中都没有定义 getString() 函数"。

"将 getString() 上面的 @Override注释掉",即可解决该错误。

2)程序运行时借助反射手段提取Annotation

在反射的 Class, Method, Field 等函数中,有许多与 Annotation 相关的接口。

这也意味着,我们可以在反射中解析并使用 Annotation。

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Inherited;
import java.lang.reflect.Method;/*** Annotation在反射函数中的使用示例*/
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {String[] value() default "unknown";
}/*** Person类。它会使用MyAnnotation注解。*/
class Person {/*** empty()方法同时被 "@Deprecated" 和 "@MyAnnotation(value={"a","b"})"所标注* (01) @Deprecated,意味着empty()方法,不再被建议使用* (02) @MyAnnotation, 意味着empty() 方法对应的MyAnnotation的value值是默认值"unknown"*/@MyAnnotation@Deprecatedpublic void empty(){System.out.println("\nempty");}/*** sombody() 被 @MyAnnotation(value={"girl","boy"}) 所标注,* @MyAnnotation(value={"girl","boy"}), 意味着MyAnnotation的value值是{"girl","boy"}*/@MyAnnotation(value={"girl","boy"})public void somebody(String name, int age){System.out.println("\nsomebody: "+name+", "+age);}
}public class AnnotationTest {public static void main(String[] args) throws Exception {// 新建PersonPerson person = new Person();// 获取Person的Class实例Class<Person> c = Person.class;// 获取 somebody() 方法的Method实例Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class});// 执行该方法mSomebody.invoke(person, new Object[]{"lily", 18});iteratorAnnotations(mSomebody);// 获取 somebody() 方法的Method实例Method mEmpty = c.getMethod("empty", new Class[]{});// 执行该方法mEmpty.invoke(person, new Object[]{});        iteratorAnnotations(mEmpty);}public static void iteratorAnnotations(Method method) {// 判断 somebody() 方法是否包含MyAnnotation注解if(method.isAnnotationPresent(MyAnnotation.class)){// 获取该方法的MyAnnotation注解实例MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);// 获取 myAnnotation的值,并打印出来String[] values = myAnnotation.value();for (String str:values)System.out.printf(str+", ");System.out.println();}// 获取方法上的所有注解,并打印出来Annotation[] annotations = method.getAnnotations();for(Annotation annotation : annotations){System.out.println(annotation);}}
}

运行结果:

somebody: lily, 18
girl, boy, 
@com.skywang.annotation.MyAnnotation(value=[girl, boy])empty
unknown, 
@com.skywang.annotation.MyAnnotation(value=[unknown])
@java.lang.Deprecated()

3) 根据 Annotation 生成帮助文档,还能够方便查看代码

通过给 Annotation 注解加上 @Documented 标签,能使该 Annotation 标签出现在 javadoc 中;

通过 @Override, @Deprecated 等,我们能很方便的了解程序的大致结构。

4>注解应用实例

注解的功能很强大,Spring和Hebernate这些框架在日志和有效性中大量使用了注解功能。注解可以应用在使用标记接口的地方。不同的是标记接口用来定义完整的类,但你可以为单个的方法定义注解,例如是否将一个方法暴露为服务。

在最新的servlet3.0中引入了很多新的注解,尤其是和servlet安全相关的注解。

HandlesTypes –该注解用来表示一组传递给ServletContainerInitializer的应用类。

HttpConstraint – 该注解代表所有HTTP方法的应用请求的安全约束,和ServletSecurity注释中定义的HttpMethodConstraint安全约束不同。

HttpMethodConstraint – 指明不同类型请求的安全约束,和ServletSecurity 注解中描述HTTP协议方法类型的注释不同。

MultipartConfig –该注解标注在Servlet上面,表示该Servlet希望处理的请求的 MIME 类型是 multipart/form-data。

ServletSecurity 该注解标注在Servlet继承类上面,强制该HTTP协议请求遵循安全约束。

WebFilter – 该注解用来声明一个Server过滤器;

WebInitParam – 该注解用来声明Servlet或是过滤器的中的初始化参数,通常配合 @WebServlet 或者 @WebFilter 使用。

WebListener –该注解为Web应用程序上下文中不同类型的事件声明监听器。

WebServlet –该注解用来声明一个Servlet的配置,用来映射访问路径和Servlet

5>我们也可以通过自定义 Annotation 来完成某个目的。

下篇博客我会亲手自定义注解完成某个目的:Java进阶知识5:自定义注解完成某个目的

 

参考链接:

Java注解基本原理

Java自定义注解

http://www.lbrq.cn/news/2518129.html

相关文章:

  • 做网站人员工资网络营销项目策划书
  • 深圳龙岗网站建设公司seo优化网
  • 网页界面设计视觉空间的三维可视化太原seo全网营销
  • 用html制作网页seo推广优化外包价格
  • seo建站技术电商seo什么意思
  • 什么网站做视频给钱网络营销环境的分析主要是
  • 做付费推广哪个网站好百度推广课程
  • 银川做网站的公司阿里云官网首页
  • 在织梦网站做静态网页舆情监测系统
  • 全国各城市疫情高峰感染高峰进度四川seo推广
  • 东莞长安网站建设百度发视频步骤
  • 网站运营及推广个人seo怎么赚钱
  • 手机网站html竞价恶意点击立案标准
  • 温州市住建委住宅建设网站百度识图搜索
  • 外贸网站推百度关键词优化软件
  • 爱写作网站fifa最新排名出炉
  • 网站建设工作自策划实施以来企业推广平台排行榜
  • 鄂州英文网站建设互联网广告公司
  • 政府网站建设领导讲话稿新站整站优化
  • 献县做网站的吉林网络推广公司
  • 网站的后台怎么做调查问卷同城推广引流平台
  • 美橙西安网站备案拍照发稿服务
  • 高端 网站建设baud百度一下
  • 帝国和WordPress比较百度seo优化公司
  • 有没有网站做悬赏的百度指数查询工具
  • 邯郸网站制作外包宁波搜索引擎优化seo
  • 旅游网站怎么做站长网站优化公司
  • 肇庆有哪家做企业网站的微信指数怎么看
  • 遵义市网站制作kol营销模式
  • 成都网站建设木木科技刷seo关键词排名软件
  • [硬件电路-106]:模拟电路 - 电路为什么会出现不同的频率特性?元件频率依赖性、信号传输路径、电路拓扑结构、外部因素
  • 【IDEA】JavaWeb自定义servlet模板
  • BT131-800-ASEMI家电领域专用BT131-800
  • umijs局域网访问警告Disconnected from the devServer,trying to reconnect...
  • c++: 尾置返回类型(Trailing Return Type)
  • 【云馨AI-大模型】2025世界人工智能大会引爆全球AI热潮,技术突破与政策布局引领产业新未来