Java学习 注解和反射

文章详细介绍了Java注解的使用,包括@Target、@Retention等元注解的作用,以及注解在字节码文件中的体现。同时,通过示例展示了如何自定义注解如@Singleton,并利用注解实现单例模式的上下文容器ApplicationContext,将带有Singleton注解的类的唯一实例存储和检索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可以在字节码文件里看到,自定义的注解类继承公共的抽象的Annotation类,Annotation类只有一些继承了父类object类的方法,自定义注解类的抽象方法,在使用注解时每个方法都需要写返回值,如果不写返回值就在定义时写上默认值,如果只定义了一个抽象方法,在写返回值的时候就不用区分方法。

@Target(ElementType .METHOD) 注解被使用在哪
ElementType enum
TYPE 类上
FIELD 属性上
METHOD 方法上
PARAMETER 参数上
CONSTRUCTOR构造器上
LOCAL VARIABLE 局部变量上
ANNOTATION TYPE 注释类型上
PACKAGE 包上

@Retention 注解被保留的时机
RetentionPolicy enum
SOURCE 保留在源代码 编译
CLASS 保留在类 加载到内存
RUNTIME 保留在运行时

JAVA的注解
元注解:在java. lang .annotation 中的
@Target
@Retention
@Document:注解是否在生成的JAVA文档中
@Inherited
@Deprecated 过时的类或方法
@SuppressWarning 压制警告 哪里都能用
String[] value();
all 抑制所有警告
boxing 抑制装箱拆箱操作时警告
finally 抑制模块没有返回的警告
fallthrough 抑制在 switch 中忽略 breaks 的警告
raw types没有使用泛型的警告
serial忽略 serializable 类没有声明serial version uid的警告
unchecked一直没有进行类型检查操作的警告
unused 抑制没有使用过的代码的警告

字节码加载到方法区以后会生成一个class对象,每一个类都会生成一个唯一的class对象。

获取class对象的方法:
类名.class
class .forName(String)
new object .get Class()
==比较内存地址
class .newInstance() 获取实例对象

field
clazz .getFields() 获取公开的类的属性返回一个数组
clazz .getDeclareFields() 获取所有类的属性
clazz .getName() for循环遍历以后获取属性的名称
name .setAccessible(true) 可以给私有属性设值
clazz .getDeclareField(String) 通过属性的名称获取属性这个对象
name .set(new object , value) 给哪个对象这个属性设置值

method
clazz .getDeclaredMethods() 获取所有的方法的名称,返回的是数组
clazz .getDeclaredMethod(String) 获取空参方法,返回的是方法的对象
clazz .getDeclaredMethod(String,argument) 获取有参方法,返回的是方法的对象
eat .invoke(对象,args) 调用方法
eat .setAccessible(true) 可以调用私有方法

constructor
clazz .getDeclaredConstructor() 创建构造器
new object .newInstance() 创建实例对象
constructor .setAccessible(true) 可以使用私有化的构造器
clazz .getDeclaredConstructor(String .class) 创建string类型的有参构造
Dog dog = constructor .newInstance(string) 给有参构造传值
dog .getName() //string

annotation
name .getAnnotation()
eat .getAnnotation()
clazz .get Annotation() 获取所有注解,返回一个注解的数组
clazz .get Annotation(MyAnnotation .class) 获取注解类的实例
sout annotation .name() .var 获取注解类方法的默认返回值

用线程获取根目录,将根目录以文件对象的形式传到方法中。方法中判断是文件夹就递归调用方法,不是就把所有的全路径添加到数组当中,并返回数组。
流式编程主要是map()、replace()根目录//以及.class,得到classForName(String),返回到数组,用工具类封装代码的细节。
只有加了@Singleton注解的类才加入容器,foreach循环遍历数组,getAnnotation()返回注解类,判断注解类不为空就调用addsingleton()把class和instance放到map中。

自定义@Singleton注解类,@Target在哪使用、@Retention保存在哪。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Singleton {
}

自定义上下文,所有加了@Singleton注解的类,都把唯一的实例对象放到上下文容器当中,需要用时从容器中调用。

public class ApplicationContext {

    public static final Map<Class<?>,Object> CONTEXT = new ConcurrentHashMap<>(8);

    public static void addSingleton(Class<?> clazz,Object entity){ //传入时不明确
        ApplicationContext.CONTEXT.put(clazz,entity);
    }

    public static <T>T getSingleton(Class<T> clazz){ //获取时明确
        Object o = ApplicationContext.CONTEXT.get(Dog.class);
        return (T)o;
    }

    public static void main(String[] args) {
        ApplicationContext.addSingleton(Dog.class,new Dog());
        System.out.println(ApplicationContext.getSingleton(Dog.class));
    }


}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值