@xxx[(一些信息)]
二.注解放置 在哪里类的上面、属性上面、方法上面、构造方法上面、参数前面、变量上面
三.注解的作用- 1.用来充当注释的作用(仅仅是一个文字的说明)
@Deprecated - 2.用来做代码的检测(验证)
@Override - 3.可以携带一些信息(内容)文件.properties .xml 注解
//小括号里写字符串的数组String[] {“”,“”} 单个元素不加大括号
//如果数组内的元素只有一个长度 可以省略{}
- unused 变量定义后未被使用
- serial 类实现了序列化接口 不添加序列化ID号
- rawtypes 集合没有定义泛型
- deprecation 方法已废弃
- unchecked 出现了泛型的问题 可以不检测
- all 包含了以上所有(不推荐)
package testannotation;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
public class TestAnnotation {
public static void main(String[] args) {
Date date=new Date();
date.getYear();
ArrayList list=new ArrayList();
System.out.println(list);
Properties properties=new Properties();
//java.util
//是HashTable的子类 是一个map类型的集合
//读取文件中的信息————流(高级流)
//读取的文件 文件后缀名.properties
//文件中的内容 以key=value形式存在的 BufferedReader readLine
//文件内容格式为:key与value之间可用等号、冒号、空格
try {
properties.load(new FileReader("src//testannotation//Test.Properties"));
String value = properties.getProperty("key1");
System.out.println(value);
@SuppressWarnings("unchecked")
Enumeration en = properties.propertyNames();//Set =map.keySet();
//iteration it.hasNext(); it.next();
//enumerationn en.hasMoreElements(); en.nextElement();
while (en.hasMoreElements()){
String key=(String) en.nextElement();
String value1 = properties.getProperty(key);
System.out.println(key+"---"+value1);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、注解中可以携带信息 可以不携带
信息不能随便写 信息的类型只能是如下的类型
1.基本数据类型
2.String类型
3.枚举类型enum
4.注解类型
5.数组类型[] 数组的内部需要是如上的四种类型
可以描述public static final的属性 (比较少见)
可以描述public abstract 的方法 方法要求返回值必须有 返回值类型是如上那几种。(基本,String,枚举,注解,数组)
方法的作用:将我们传递的信息,搬走了,交给别人。
元注解(也是注解 不是拿来使用的 是用来说明注解)
- @Target 描述当前的这个注解可以放置在哪里写的(属性、方法、构造方法等)
- @Retention 描述当前的这个注解存在什么作用域中的
源代码文件—>编译---->字节码文件---->加载----->内存执行
SOURCE----> ----> CLASS-----> ----->RUNTIME - @Inherited 描述当前这个注解是否能被子类对象继承
- @Document 描述这个注解是否能被文档所记录
问题1.在注解里面描述了一个方法,方法没有参数,方法是有返回值String[]
使用注解的时候,让我们传递参数。理解为,注解的方法做事,将我们传递给他的参数搬运走了,给了别人。
问题2.使用别人写好的注解不用写方法名,我们自己定义的方法必须写名字?
如果我们自己定义的注解,只有一个方法,方法名字叫value,在使用的时候就可以省略方法名。如果传递的信息是一个数组,数组内只有一个元素,可以省略{}。如果方法是两个以上,每一个方法必须写名字。
package testannotation;
import java.lang.annotation.*;
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
public abstract String test();//注解的方法要求必须有返回值 类型是我们总结的那些
}
package testannotation;
public class Person {
@MyAnnotation(test = "abc")
private String name;
}
七、如何返问到注解对象
如何获取里面的额信息(需要反射机制)
package myselfannotation;
import myselfannotation.MyAnnotation;
public class Person {
@MyAnnotation({"柳先生","18","男"})
private String name;
}
package myselfannotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public abstract String[] value();//默认方法---->属性
}
package myselfannotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) {
try {
//解析Person类中 属性上面的注释信息 需要用到反射技术
//1.获取Person对应的类Class
Class clazz=Person.class;
//2.通过clazz获取里面的属性
Field field = clazz.getDeclaredField("name");
//3.通过filed获取上面的注解对象
Annotation a = field.getAnnotation(MyAnnotation.class);
//4.通过反射执行a的value方法
Class aclazz= a.getClass();//a对象获取它对应的class
//5.通过aclazz获取里面的value属性
Method amethod = aclazz.getMethod("value");
//6.执行value的方法 获取传递的信息
String[] values=(String[]) amethod.invoke(a);
//7.展示一下values内的信息
for (String value:values){
System.out.println(value);
}
//正常的对象调用执行过程
// MyAnnotation a = field.getAnnotation(MyAnnotation.class);
// //4.利用a对象执行一下value方法 帮我们搬运过来啦
// String[] values = a.value();
// System.out.println(values[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package myselfannotation;
import myselfannotation.MyAnnotation;
public class Person {
@MyAnnotation({"柳先生","18","男"})
private String name;
@MyAnnotation({"张先生","17","男"})
public void eat(){}
}
package myselfannotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) {
try {
//获取Person类中 方法上面的注解信息 反射
Class clazz=Class.forName("myselfannotation.Person");
Method method = clazz.getMethod("eat");
Annotation a = method.getAnnotation(MyAnnotation.class);
Class aclazz = a.getClass();
Method amethod= aclazz.getMethod("value");
String[] values=(String[])amethod.invoke(a);
for (String v:values){
System.out.println(v);
}
// //解析Person类中 属性上面的注释信息 需要用到反射技术
// //1.获取Person对应的类Class
// Class clazz=Person.class;
// //2.通过clazz获取里面的属性
// Field field = clazz.getDeclaredField("name");
// //3.通过filed获取上面的注解对象
// Annotation a = field.getAnnotation(MyAnnotation.class);
// //4.通过反射执行a的value方法
// Class aclazz= a.getClass();//a对象获取它对应的class
// //5.通过aclazz获取里面的value属性
// Method amethod = aclazz.getMethod("value");
// //6.执行value的方法 获取传递的信息
// String[] values=(String[]) amethod.invoke(a);
// //7.展示一下values内的信息
// for (String value:values){
// System.out.println(value);
// }
//正常的对象调用执行过程
// MyAnnotation a = field.getAnnotation(MyAnnotation.class);
// //4.利用a对象执行一下value方法 帮我们搬运过来啦
// String[] values = a.value();
// System.out.println(values[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
八、注解在开发汇总应用的场景
如何利用反射技术,解析注解(内部的额携带的信息)
1.获取类Class
2.获取类中的成员:类,属性,方法,构造方法
3.Annotation a=成员.getAnnotation(注解类型.class);
4.注解对象 执行方法获取返回结构
package myselfannotation;
public class Person {//domain实体对象 建议大家利用包装类
private String name;
private Integer age;
private String sex;
@MyAnnotation({"柳先生","18","男"})
public Person(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package myselfannotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MySpring {
//设计一个方法 给一个类名字 返回一个对象 对象内的属性值存在着
public Object getBean(String className){
Object obj=null;//变量接收最终的对象
try {
//1.通过传递的className来获取对应的类Class
Class clazz=Class.forName(className);//要求参数是一个类全名
//2.通过clazz创建一个空的对象
//obj=clazz.newInstance();
Constructor con = clazz.getConstructor();//找到的是无参数的构造方法
obj= con.newInstance();
//3.创建对象以后 将对象内的所有属性自动赋值DI
//值--->文件 好处在于代码包装起来.jar不能修改 文件还可以修改
//.xml 不好在于开发的时候 源代码和配置文件不在一起 读取/修改比较困难
//值--->注解 好处在于开发的时候方便 源代码和注解在一起 读取/调整时候比较容易
//@ 不好在于代码包装起来以后 注解内携带的信息不能修改
//4.首先获取属性的值---->类的无参数构造方法之上
Annotation a=con.getAnnotation(MyAnnotation.class);
//5.获取a注解对象内携带的信息--->person对象所有的属性值
Class aclazz = a.getClass();
Method amethod=aclazz.getMethod("value");
String[] values=(String[]) amethod.invoke(a);
//6.将values中的每一个值 对应的赋给属性
//找寻属性对应的set方法属性
Field[] fields=clazz.getDeclaredFields();//获取全部的私有属性
for (int i=0;i
package myselfannotation;
public class TestMain {
public static void main(String[] args) {
try {
//获取一个Person对象 不用自己处理 跟别人要 MySpring
//对象的创建权力(IOC) 赋值(自动DI)别人处理
MySpring ms=new MySpring();//管理者 帮我们创建对象 自动赋值
Person p= (Person) ms.getBean("myselfannotation.Person");
System.out.println(p.getName()+"——"+p.getAge()+"——"+p.getSex());
} catch (Exception e) {
e.printStackTrace();
}
}
}



