注解

1、在java1.5版本后可以在源代码补充信息,这种补充信息成为注解Annotation,属于一种interface类型。
2、注解不改变运行程序的结果、以及性能。注解可以在编译时给用户提示、警告还有运行时读写字节码。
3、注解也称元数据。就是源代码的元数据,就是一种描述数据的数据。
@Override
public String toString(){return "注解是元数据";}
//Override可以防止代码写错确保父类要有该方法,表示重写父类方法。
4、注解的常见作用:
a、生成帮助文档---最常见,有@see、@param、@return等
b、跟踪代码依赖,如spring2.5开始基于注解配置,减少配置。
c、在编译时进行格式检查。如Override
5、无论什么注解,本质都是一种数据类型,一种接口类型。java8提供了11个内置注解,
5个基本注解,来自java.lang包;6个元注解来自java.lang.annotation包--自己定义的注解会用到元注解。
6、基本注解:OverrideDeprecatedSuppressWarningsSafeVarargs 1.8 FunctionlInterface.
7、元注解:DocumentedTargetRetentionInherited 1.8 RepeatableNative--负责注解的注解。

 待详细透彻:Repeatable,native

=============================================

===========================================

@Override

//解决代码重写写错问题
public class Override1 {
private String name;
private int age;
@Override
public String toString(){
return "Person name is "+ name +"age is"+age;
}
}

/@Deprecated

//@Deprecated用来注解已经过时的---可以注解类,接口,方法,变量
//扩展:java9为其添加了两个属性since(指定哪个版本开始过时int)、forRemoval(将来是否被删除boolean)
@Deprecated
public class Deprecated1 {
@Deprecated
protected String name;
private int age;
@Deprecated
public int getAge() {
return age;
}
//@Deprecated(since="9" forRemoval=true)--由于我用的还是jdk8,所以不能用
public void setAge(int age) {
this.age = age;
}
}

@SuppressWarnings

//SuppressWarnings--父类有压制,则其所有子类也会自带
//作用解决编译产生的警告影响到断点
public class SuppressWarnings1 {
@SuppressWarnings({"unchecked","cast"})//一个的话可以省略{}
public static void main(String[] args) {
Object o = new Object();//The value of the local variable o is not used
}
}
//抑制单类型的警告:@SuppressWarnings("unchecked")
//抑制多类型的警告:@SuppressWarnings("unchecked","rawtypes")
//抑制所有类型的警告:@SuppressWarnings("unchecked")
//对应关键字

@SafeVarargs

public class SafeVarargs1 {
public static void main(String[] args) {
//传递可变参数,参数是泛型集合
display(10,20,30);
//传递可变参数,参数非泛型集合
display("lang",20,30);//没有SafeVarargs会有警告
}
/*
private static void display(int i, int j, int k) {
// TODO Auto-generated method stub
}*/
@SafeVarargs
private static <T> void display(T ... array) {//没有SafeVarargs会有警告
// TODO Auto-generated method stub
for(T arr : array){
System.out.println(arr.getClass().getName()+":"+ arr);//java.lang.Integer:10....
}
}
}

@FunctionalInterface

//1.8Lambda的到来,java特地增加了FunctionalInterface注解,目的式保证只有一个抽象方法,可以达到函数式接口形式。
//Lambda表达式:函数式接口---接口中只有一个抽象方法(可以多个默认方法和static方法)
@FunctionalInterface//保证只有一个抽象方法,可以达到函数式接口形式
public interface FunctionalInterface1 {
//接口中出抽象方法,其它方法都有方法体
static void print(){
System.out.println("静态方法");
}
default void show(){
System.out.println("默认方法");
}
void test();//抽象方法
}

=============================================

===========================================

@Documented

//Documented注解的类会被JavaDoc攻具提取成文档
//由于元注解式注解的注解,所以需要在接口或者其它地方上加上@
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})//指名要加注解的目标位置,也就是@Documented1的位置
public @interface Documented1 {
//public String value() default "这是@Documented注解";
public String value() default "这是@Documented注解";
}

@Documented1
public class DocumentedTest {
public String Test(){
return "Document注解测试";
}
}

打开 Java 文件所在的目录,分别输入如下两条命令行

d: 到d盘

D:logcodelogsrccomlkwannotation

javac Documented1.java DocumentedTest.java
javadoc -d doc Documented1.java DocumentedTest.java
再去源程序的位置会看到一个doc的文件,打开就有一些html,点开就可以看到这么文档了。



@Target--value值是什么就可以再哪里修饰

@Target({ElementType.METHOD})
public @interface Target1 {
}
class TargetTest{
@Target1
public void test(){};
}

@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组,下表为 ElementType 常用的枚举常量。

@Retention
SOURCE:在源文件中有效(即源文件保留)
CLASS:在 class 文件中有效(即 class 保留)
RUNTIME:在运行时有效(即运行时保留---默认级别,比较重要
生命周期大小排序为 SOURCE < CLASS < RUNTIME,前者能使用的地方后者一定也能使用。
如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;
如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS 注解;
如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解

@Inherited:只要被该注解注解的注解修饰,则其子类都默认拥有

@Target(ElementType.TYPE)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Inherited1 {
}

//@Inherited1--这样写是不能编译的
//class TestA{
// public static void main(String[] args) {
// System.out.println(TestA.class);
// System.out.println();
// System.out.println();
// }
//}
//class TestB extends TestA{}
//class TestC extends TestB{}

@Inherited1
public class TestA {
public static void main(String[] args) {
System.out.println(TestA.class);//class com.lkw.annotation.TestA
System.out.println(TestA.class.getAnnotation(Inherited1.class));//@com.lkw.annotation.Inherited1()
System.out.println(TestB.class.getAnnotation(Inherited1.class));//@com.lkw.annotation.Inherited1()
System.out.println(TestC.class.getAnnotation(Inherited1.class));//@com.lkw.annotation.Inherited1()
}
}
class TestB extends TestA{}
class TestC extends TestB{}

在需要对同一种注解多次使用时,往往需要借助 @Repeatable 注解。就不要重复创建了,省的麻烦

@Repeatable

//都是伪代码,其中Role是引入注解
//A{B}---多个B的使用,1.8后只要创建一个B+@Repetable,相当于工厂模式这个注解
/*@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Repeatable1 {
Role[] roles();
}
public @interface Repeatable1 {
Role[] value();
}
class RepeatableTest{
@Repeatable1(roles={@Role(roleName="role1"),@Role(roleName="role2")})
public String doString(){
return "1.8之前";
}
}*/

/*public @interface Repeatable1{
Role[] value();
}
@Repeatable(Repeatable1.class)
public @interface Role{
String roleName();
}
class Repeatable1Test(){
@Role("roleName=role1")
@Role("roleName=role2")
public String doString(){
return "1.8之后";
}
}*/

@Native

使用 @Native 注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。对

于 @Native 注解不常使用,了解即可

======================

=========================

自定义注解----注意成员基本可以各种数据类型

//如果自定义注解有成员变量,要么在使用该注解时全部赋值--必需
//要么定义注解时默认赋值--在使用时如果默认的在使用时也写出来了,则覆盖默认,如下password
public @interface UserDefine {
String name();
int age();
String password() default "123456";
}
class UserDefineTest{
@UserDefine(age = 0, name = "",password="21")
public void info(){

}
}

=========================

==================

自定义通过反射获取注解类,方法,属性--下面有个排序是自己懒没分开写,排序所有代码野有

public class KeyValueDto implements Comparable<KeyValueDto>{
private String key;
private String value;
public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public KeyValueDto(String key, String value) {
super();
this.key = key;
this.value = value;
}

@Override
public String toString() {
return "KeyValueDto [key=" + key + ", value=" + value + "]";
}

@Override
public int compareTo(KeyValueDto o) {
// TODO Auto-generated method stub
return o.getKey().compareTo(this.key);
}
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ByReflactGetAnnotationOfs {
String name() default "";
}

public class TestAnnotation {
public final Integer NUMBER=10000;

@ByReflactGetAnnotationOfs(name="方法注解1")
public void test1(){
System.out.println("方法体1");
}

@ByReflactGetAnnotationOfs
public void test2(){
System.out.println("方法体2");
}

@ByReflactGetAnnotationOfs
public void test3(){
System.out.println("方法体3");
}
}

public class TestGetAnnotionalMethodField {

public static void main(String[] args) {
testJava();
}

public static <T> void testJava() {
Class<?> printClass = null;

//KeyValueDto时实体类返回的时map
//List<KeyValueDto> list = new ArrayList<>();//都有用
List<KeyValueDto> list = new ArrayList();
try{
//获取类的路径
printClass = Class.forName("com.lkw.annotation.TestAnnotation");
//反射机制获取所有对应的注解名称
Method[] declareMethods = printClass.getDeclaredMethods();
//遍历循环方法并获得对应的注解名称
for(Method declareMethod : declareMethods){
String isNotNull=" ";
//判断方法上是否存在注解---@ByReflactGetAnnotationOfs
boolean annotationExist = declareMethod.isAnnotationPresent(ByReflactGetAnnotationOfs.class);
if(annotationExist){
//获取自定义注解对象
ByReflactGetAnnotationOfs methodAnno = declareMethod.getAnnotation(ByReflactGetAnnotationOfs.class);
System.out.println(methodAnno);//@com.lkw.annotation.ByReflactGetAnnotationOfs(name=方法注解1)
//获取自定义注解接//方法注解1
isNotNull = methodAnno.name();
System.out.println(isNotNull);
//下面时注解方法名//test1
isNotNull = declareMethod.getName();
System.out.println(isNotNull);
}
//排序
Collections.sort(list);
System.out.println(list.toString());
}
}catch(Exception e){
e.printStackTrace();
}
}


}
/*@com.lkw.annotation.ByReflactGetAnnotationOfs(name=方法注解1)
方法注解1
test1
[]*/

原文地址:https://www.cnblogs.com/lkwcrystal/p/12371884.html