注解
注解声明
声明一个注解类型
java中的所有的注解,默认实现Annotation接口:

声明一个"class"不同的是,注解的声明使用@interface关键字。一个注解的声明如下:
public @interface Lance{
}
元注解
在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解类,我们称之为 meta-annotation(元注解),一般,我们在定义自定义注解时,需要指定的元注解有两个:
@Target
注解标记标记另一个注解,以限制可以应用注解的java元素类型。目标注解指定以下元素类型之一作为其值:

@Retention
注解指定标记注解的存储方式:
RetentionPolicy.SOURCE - 标记的注解仅保留在源码级别中,并被编译器忽略。
RetentionPolicy.CLASS - 标记的注解在编译时由编译器保留,但Java虚拟机(JVM)会忽略
RetentionPolicy.RUNTIME - 标记的注解由JVM保留,因此运行时环境可以使用它。
@Retention三个值中SOURCE < CLASS < RUNTIME ,即CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS。下文会接介绍他们的不同应用场景。


注解类型元素
在上文元注解中,允许在使用注解时传递参数。我们也能让自定义注解的主体包含annotation type element(注解类型元素)声明,它们看起来很像方法,可以定义可选的默认值。



了解反射
反射之中包含了一个【反】字,所以了解反射我们先从【正】开始,
一般情况下我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例话,之后使用这个类对象进行操作。
Shap shap = new Shap();
shap.geCorlor();
反射是开始并不知道我们要初始化的对象是什么,自然也无法使用new关键字来创建对象了。这时候,我们使用JDK提供的反射API进行反射调用。
Class shapeClass = Class.forName("com.example.use.Shape");
Shape shapeInst = (Shape) shapeClass.newInstance();
Log.i("TAG","init: "+shapeInst.toString());
举例:通过反射获取类的几种方式
Date date =new Date();
Class da = date.getClass();
Class da2 = Date.class;
Class da3 = Class.forName("java.util.Date");
Date da4 = (Date) da3.newInstance();
da4.setDate(1);
反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
// 获取类所有构造方法
Constructor[] constructors = da.getConstructors();
for (Constructor c : constructors){
Log.i("constructors","获取类所有构造方法: "+c);
}
// 获取某指定构造方法
Constructor constructor = da.getConstructor(int.class,int.class,int.class);
Log.i("constructors","获取某指定构造方法:--- "+constructor);
try {
Date date1 = constructor.newInstance(1,2,3);
Log.i("constructors","time:--- "+date1.getTime());
}catch (InvocationTargetException e) {
e.printStackTrace();
}
反射获取构造方法,并设置值
Method[] methods = date.getDeclaredMethods();
for (int i =0; i < methods.length; i++) {
Log.i("intMethod","intMethod: "+methods[i].getName());
}
Method setYear = date.getDeclaredMethod("setYear",int.class);
Date date1 = (Date) date.newInstance();
setYear.invoke(date1,1000);
Log.i("intMethod","intMethod: "+setYear+"---"+date1.getYear());
反射修改成员变量的值
public class Person {
private int age;
private Stringname;
public Person() {
}
public Person(int age) {
this.age = age;
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public Person(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person person =new Person(333,"我");
Class cl = person.getClass();
Field fiAge = cl.getDeclaredField("age");
fiAge.setAccessible(true);
Object o = fiAge.get(person);
fiAge.set(person,222);//私有方法必须先设置为true
Log.i("person","setfield: "+person.getAge());
2022-10-09 00:48:40.872 3893-3893/com.example.myapplication I/person: setfield: 222
网友评论