注解
- 注解就是可以放在类上,方法上或者属性上的一个类似于属性的东西,可以自己设定可以加在哪里,可以让程序看得懂。注解使用通过@注解名 来使用
- 常见的比如说重写@Override这种
- 自定注解需要添加的注解:
- @Target:表示使用的范围,类上方法上属性上
- @Retention:表示在什么级别保存该注释信息
- SOURCE:源代码级别
- CLASS:元数据级别
- RUNTIME:运行时级别
- @Document:将该注解包含在javadoc中
- @Inherited:子类可以继承父类的该注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
String value() default "";
}
@MyAnnotation("111")
public class ListTest{
}
反射
- Java是一门静态语言,通过反射可以让Java变成一门准动态语言,通过反射可以动态的获取运行时对象的所有信息,类被加载后会被封装在一个Class中
- 获取Class的三种方式
- 类名.class
- 对象.getClass()
- Class.forName(“类的全类名”)
- 反射提供的功能:
- 运行时构造类的对象
- 运行时获取类的成员变量和方法
- 运行时处理注解
- 运行时调用成员变量和方法
- 生成动态代理
- 有Class对象的类型
- class:所有类都有
- interface:接口
- [] :数组
- enum:枚举
- annotation:注解
- void:空
- 字段类常用方法:
public class TestField {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> clazz = Class.forName("com.example.test.reflect.Student");
System.out.println(Arrays.toString(clazz.getFields()));
System.out.println(Arrays.toString(clazz.getDeclaredFields()));
Field id = clazz.getDeclaredField("id");
System.out.println(Arrays.toString(id.getDeclaredAnnotations()));
System.out.println(id.getDeclaredAnnotation(FieldTest.class).value());
System.out.println(id.getGenericType());
System.out.println(id.isAnnotationPresent(FieldTest.class));
for (Annotation annotation : id.getAnnotations()) {
if(annotation.annotationType().equals(FieldTest.class)){
System.out.println(true);
}
}
}
}
@Data
class Student{
@FieldTest(value = "ccc",aa = "aa")
private int id;
private String name;
protected String monName;
private int age;
public String brotherName;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTest{
String value() default "";
String aa();
}
package com.example.test.reflect;
import lombok.Data;
import lombok.Value;
import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestMethod {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> clazz = Class.forName("com.example.test.reflect.Model");
Object o = clazz.newInstance();
System.out.println(Arrays.asList(clazz.getDeclaredMethods()));
Method bb = clazz.getDeclaredMethod("bb", String.class);
bb.setAccessible(true);
System.out.println(bb.invoke(o, "ccc"));
System.out.println(bb.getDeclaredAnnotation(MethodTest.class).value());
System.out.println(bb.getReturnType().getName().equals("java.lang.String"));
}
}
@Data
class Model{
public void aa(){
}
@MethodTest("method")
private String bb(String aaa){
return aaa;
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MethodTest{
String value() default "";
String aa() default "";
}
package com.example.test.reflect;
import lombok.Data;
import lombok.Value;
import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestConstructor {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> clazz = Class.forName("com.example.test.reflect.Con");
System.out.println(Arrays.asList(clazz.getDeclaredConstructors()));
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor();
Object o = declaredConstructor.newInstance();
Con con = (Con)o;
}
}
@Data
class Con{
public Con(){
}
}