网站首页 > java教程 正文
基于注释的Java开发无疑是最近最显着的发展趋势之一。基于注释的开发使Java开发人员免于繁琐的配置困扰。最初在Java 5.0中引入,注释是JDK版本中的一个特性,它将编写样板Java代码的责任从编程器转移到编译器。当源代码没有样板代码时,它就变得更容易维护。生成的代码也不太可能包含错误。
Java注释是JDK 5中引入的主要易于开发的特性之一。注释就像元标记,您可以将其添加到代码中并应用于包声明,类型声明,构造函数,方法,字段,参数和变量。它们提供了一种有用的方法来指示您的方法是否依赖于其他方法,它们是否不完整,您的类是否引用了其他类,等等。
引用Oracle的官方网站 “它[基于注释的开发]”让我们避免在许多情况下编写样板代码,方法是让工具从源代码中的注释中生成它。这导致了一种声明性编程风格,程序员说应该是什么完成和工具发出代码来完成它。
简单来说,注释是一种机制,用于将元标记与程序元素相关联,并允许编译器或VM从这些带注释的元素中提取程序行为,并在必要时生成相互依赖的代码。
在这篇三篇文章系列的第一部分中,我将介绍Java注释的一些基础知识,它们的好处,以及提供一些示例用法。
Java注释基础知识
使用注释需要考虑两件事。一个是“注释”本身; 另一个是“注释类型”。注释是您将在代码中使用的元标记,以赋予它一些生命。注释类型用于定义注释。当您想要创建自己的自定义注释时,将使用它。类型是使用的实际构造,注释是该类型的特定用法。
注释类型定义采用“at”(@)符号,后跟interface关键字和注释名称。另一方面,注释采用“at”符号(@)的形式,后跟注释类型。这是最简单的注释形式。此外,您可以在注释名称后面的括号内放置数据。每个例子如下所示:
定义注释的示例(注释类型)
public @interface MyAnnotation { String doSomething(); } MyAnnotation(doSomething =“做什么”) public void mymethod(){ .... }
Java注释类型
有三种注释类型:
- 标记:标记类型注释除了注释名称本身外没有任何元素。
- 例:
public @interface MyAnnotation { }
- 用法:
@MyAnnotation public void mymethod(){ .... }
- 单元素:单元素或单值类型注释仅提供单个数据。这可以用数据=值对表示,或者仅用括号内的值(快捷语法)表示。
- 例:
public @interface MyAnnotation { String doSomething(); }
- 用法:
@MyAnnotation(“怎么做”) public void mymethod(){ .... }
- 全值或多值:全值类型注释具有多个数据成员。因此,必须为每个成员使用完整的data = value参数语法。
- 例:
public @interface MyAnnotation { String doSomething(); int count; 字符串日期(); }
- 用法:
@MyAnnotation(doSomething =“做什么”,count = 1, date =“09-09-2005”) public void mymethod(){ .... }
用于定义Java注释类型的经验法则
以下是定义注释类型时的一些经验法则:
- 注释声明应以@之后的'at'符号开头,后跟一个interface关键字,后跟注释名称。
- 方法声明不应该有任何参数。
- 方法声明不应该有任何throws子句。
- 该方法的返回类型应为以下之一:
- 原语
- 串
- 类
- 枚举
- 以上类型的数组
Java注释类型
JDK5提供两种类型的注释:
- 简单注释:这些是Tiger提供的基本类型,您只能使用它来注释代码; 您不能使用它们来创建自定义注释类型。
- 元注释:这些是为注释注释类型声明而设计的注释类型。简单来说,这些被称为注释注释。
JDK5只提供三种简单注释。他们是:
- 覆盖
- 弃用
- Suppresswarnings
重要的是要注意JDK5(换句话说,Tiger)实际上没有很多内置注释; 相反,它允许核心Java支持注释功能。JSR-175的章程严格规定它是定义元数据设施。程序员需要编写自定义注释类型,并向其他JSR编写一组标准注释类型。以下部分将更详细地描述每个简单注释以及示例。
Override注释
Override注释指示需要带注释的方法来覆盖超类中的方法。如果具有此批注的方法未覆盖其超类的方法,则编译器将生成错误。示例1演示了Override注释:
Java注释示例1
public class Test_Override { @Override public String toString() { return super.toString() + " Testing annotation name: 'Override'"; } }
如果方法名称出现拼写错误会怎样?例如,如果将toString方法的名称更改为“tostring”并编译代码,则会得到如下内容:
Compiling 1 source file to D:tempNew Folder (2) TestJavaApplication1buildclasses D:tempNew Folder (2)TestJavaApplication1srctest myannotationTest_Override.java:24: method does not override a method from its superclass @Override 1 error BUILD FAILED (total time: 0 seconds) Deprecated Deprecated
Deprecated注释
此注释表示当使用不推荐使用的程序元素时,编译器应该向您发出警告。示例2显示了不推荐使用的注释。
Java注释示例2
首先,使用不推荐的方法创建一个类,如下所示:
public class Test_Deprecated { @Deprecated public void doSomething(){ System.out.println(“Testing annotation name:'Deprecated'”); } }
接下来,尝试从另一个类调用此方法:
public class TestAnnotations { public static void main(String arg [])throws Exception { new TestAnnotations(); } public TestAnnotations(){ Test_Deprecated T2 =新Test_Deprecated(); t2.doSomething(); }
此示例中的doSomething()方法声明为不推荐使用的方法。因此,当此类由其他类实例化时,不应使用此方法。如果编译Test_Deprecated.java,编译器将不会生成任何警告消息。但是,如果您尝试编译使用弃用方法的TestAnnotations.java,您将看到如下内容:
Compiling 1 source file to D:tempNew Folder (2)TestJavaApplication1buildclasses D:tempNew Folder (2)TestJavaApplication1srctestmyannotation TestAnnotations.java:27: warning: [deprecation] doSomething() in test.myannotation.Test_Deprecated has been deprecated t2.doSomething(); 1 warning
SuppressWarnings注释
此注释指示应在注释元素及其所有子元素中屏蔽编译器警告。元素中抑制的警告集是所有包含子元素中警告的超集。例如,如果您注释一个类以禁止一个警告及其一个方法来抑制另一个警告,则两个警告将仅在方法级别被抑制。有关suppresswarnings注释,请参见示例3。
Java注释示例3
public class TestAnnotations { public static void main(String arg [])throws Exception { new TestAnnotations()。doSomeTestNow(); } @SuppressWarnings({“deprecation”}) public void doSomeTestNow(){ Test_Deprecated t2 = new Test_Deprecated(); t2.doSomething(); } }
在此示例中,您将抑制示例2中显示的方法列表的弃用警告。由于该方法被禁止,因此您不太可能再查看“弃用”警告。
注意:在最有效的嵌套元素中使用此注释是个好主意。因此,如果要在特定方法中禁止警告,则应该注释该方法而不是其类。
元注释(Java注释类型)
元注释实际上称为注释注释,包含四种类型。这些是:
- 目标
- 保留
- 记录
- 遗传
目标注释
目标注释指示注释类型适用的类的目标元素。它包含以下枚举类型作为其值:
- @Target(ElementType.TYPE) - 可以应用于类的任何元素
- @Target(ElementType.FIELD) - 可以应用于字段或属性
- @Target(ElementType.METHOD) - 可以应用于方法级别注释
- @Target(ElementType.PARAMETER) - 可以应用于方法的参数
- @Target(ElementType.CONSTRUCTOR) - 可以应用于构造函数
- @Target(ElementType.LOCAL_VARIABLE) - 可以应用于局部变量
- @Target(ElementType.ANNOTATION_TYPE) - 表示声明的类型本身是注释类型
示例4演示了目标注释:Java注释示例4
首先,使用@Target元数据定义名为Test_Target的注释,如下所示:
@Target(ElementType.METHOD) public @interface Test_Target { public String doTestTarget(); }
接下来,创建一个将使用Test_Target注释的类:
public class TestAnnotations { public static void main(String arg []){ new TestAnnotations()。doTestTarget(); } @Test_Target(doTestTarget =“Hello World!”) public void doTestTarget(){ System.out.printf(“Testing Target annotation”); } }
@Target(ElementType.METHOD)表示此注释类型只能用于在方法级别进行注释。如果编译上述代码,则不会显示警告消息。现在,如果声明一个String变量并应用新创建的注释,会发生什么?让我演示如下:
public class TestAnnotations { @Test_Target(doTestTarget =“Hello World!”) private String str; public static void main(String arg []){ new TestAnnotations()。doTestTarget(); } 公共无效doTestTarget(){ System.out.printf( “测试目标注解”); } }
您可以从上面看到的唯一变化是注释声明从方法级别转移到字段级别,这是不正确的。因为您已将注释@Test_Target定义为仅适用于方法级别,所以如果您尝试编译此类,则可能会得到如下内容:
"TestAnnotations.java": D:R_AND_DTestAnnotationsrctestmyannotation TestAnnotations.java:16: annotation type not applicable to this kind of declaration at line 16, column 0 @Test_Target(doTestTarget="Hello World !") ^ Error in javac compilation
Retention注释
保留注释指示要保留此类型注释的位置和时长。有三个值:
- RetentionPolicy.SOURCE - 具有此类型的注释将仅保留在源级别,编译器将忽略
- RetentionPolicy.CLASS -编译时将由编译器保留此类型的注释,但VM将忽略它们
- RetentionPolicy.RUNTIME - VM将保留此类型的注释,因此只能在运行时读取它们
示例5显示了RetentionPolicy.RUNTIME值的作用:
Java注释示例5
@Retention(RetentionPolicy.RUNTIME) public @interface Test_Retention { String doTestRetention(); }
在此示例中,@ Retention(RetentionPolicy.RUNTIME)注释指示VM将保留您的Test_Retention注释,以便在运行时可以反射性地读取它。
记录注释
记录的注释表明javadoc工具应记录此类型的注释。默认情况下,注释不包含在javadoc中。但是如果使用了@Documented,它将由类似javadoc的工具处理,注释类型信息也将包含在生成的文档中。示例6演示了进一步使用@Documented:
Java注释示例6
@Documented public @interface Test_Documented { String doTestDocument(); }
接下来,更新TestAnnotations类,如下所示:
public class TestAnnotations { public static void main(String arg []){ new TestAnnotations()。doSomeTestRetention(); new TestAnnotations()。doSomeTestDocumented(); } @Test_Retention(doTestRetention =“Hello retention test”) public void doSomeTestRetention(){ System.out.printf(“Testing annotation'Retention'”); } @Test_Documented(doTestDocument =“Hello document”) public void doSomeTestDocumented(){ System.out.printf(“Testing annotation'Documented”“); } }
现在,如果您运行javadoc命令并查看生成的TestAnnotations.html文件,您将看到如图1所示的内容。
从屏幕截图中可以看出,doSomeTestRetention()方法没有注释类型信息。但是,此描述是为doSomeTestDocumented()方法提供的。这是因为附带了Test_Documented注释的@Documented标记。您之前的注释Test_Retention未包含此标记。
Inherited注释
这是一个复杂的注释类型。它表示具有此类型的带注释的类是自动继承的。更具体地说,如果使用@Inherited标记定义注释,然后使用注释注释类,最后在子类中扩展该类,则父类的所有属性都将继承到其子类中。通过示例7,您将了解使用@Inherited标记的好处。
Java注释示例7
首先,定义注释:
@Inherited public @interface myParentObject { boolean isInherited() default true; String doSomething() default "Do what?"; }
接下来,使用您的注释注释一个类:
@myParentObject public Class myChildObject { }
如您所见,您不必在实现类中定义接口方法。由于使用了@Inherited标记,因此会自动继承这些标记。如果用老式的Java风格定义实现类会发生什么?看看这个 - 以旧式java方式定义实现类:
public class myChildObject implements myParentObject { public boolean isInherited() { return false; } public String doSomething() { return ""; } public boolean equals(Object obj) { return false; } public int hashCode() { return 0; } public String toString() { return ""; } public Class annotationType() { return null; } }
你看得到差别吗?您可以看到,您必须实现父接口拥有的所有方法。除了myParentObject中的isInherited()和doSomething()方法之外,您还必须实现java.lang.Object的equals(),toString()和hasCode()方法以及java.lang的annotationType()方法。 annotation.Annotation类。是否要实现这些方法并不重要; 您必须将这些包含在继承的对象中。
结论
本文向您展示了如何通过使用JDK5的注释功能使您的开发更容易。注释不会直接影响程序的语义。开发和部署工具可以读取这些注释并以某种方式处理它们,可能会生成其他Java编程语言源文件,XML文档或其他工件,以与包含注释的程序一起使用。您现在可以执行与以前相同的操作,但代码更少,编译时错误检测更好。目标是花更少的时间在不方便的代码编写上,更多地关注业务逻辑规则。本文是Java Annotations系列文章的第一部分。在第二部分中,您将学习如何使用注释开发一个带有平面表的简单Web应用程序。
最近搜集了一些编程学习资料,需要的小伙伴可以私聊我“学习”来进行领取,希望可以帮助到你。
猜你喜欢
- 2024-09-16 拼多多技术3面(Java研发):幻影读+Redis+分布式缓存+锁机制
- 2024-09-16 用java帮助你判断一个数是不是回文数
- 2024-09-16 java之解析复杂json(含源码)(java解析复杂json格式数据)
- 2024-09-16 “全栈2019”Java多线程第四十一章:读锁与写锁之间相互嵌套例子
- 2024-09-16 java开发神器IntelliJ IDEA CE 2019.2汉化版
- 2024-09-16 史上最强Java NIO入门:担心从入门到放弃的,请读这篇
- 2024-09-16 读Java实战(第二版)笔记01_Java的变化
- 2024-09-16 语言拟人向:来自Python、JAVA、C语言的“傲娇”自我介绍
- 2024-09-16 Java编程入门100例之四十五(读文件)
- 2024-09-16 读Java性能权威指南(第2版)笔记24_ Java飞行记录器JFR
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)