Day14 注解和反射学习

Day14

注解和反射

注解

注释是给人看的,注解不仅给人看还给程序来看

Annotation 可以被其他程序读取

重写的注解 Override

格式就是@ +注释名 在代码中很常见

注解能在很多地方使用 ,比如包 类 方法 通过反射机制来对元数据进行访问

内置注解

@Override 定义在java.lang.Override 方法声明表示打算重写父类的方法。

@SuppressWarnings 用来抑制编译的警告问题 这个需要添加一个参数才能进行。

元注解

作用就是负责注解其他注解,java定义了四个标准的meta-annotation类,用来提供对其他annotation类的解释说明。

@Target @Retention @Documented @Inherited

Target 用来描述注解的使用范围

Retention 表示用什么级别保存该注释信息,用于描述注解的生命周期 (SOURCE<ClASS<RUNTIME)

Documented 表示该注解会被包含在Javadoc里面

Inherited 说明子类可以继承父类的该注解。

正常是选择运行是有效,所以就是RetentionPolicy.RUNTIME

自定义注解

使用@interface来定义

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface myannotation{
    //注解的参数,由参数类型+参数名字+()   在使用该注解时就需要加参数   也可以用default来设置默认值
    String name()  default " ";  
    int age()  default -1;//如果默认值为-1就代表不存在

}

如果注解只有一个参数,可以使用value命名,在使用时不写参数名用value直接写值

思考一下,写注解有什么用,前面了解到注解是给人喝程序看的修饰性语句 这些注解携带参数,会不会起到传递参数的作用

要学习反射机制才能了解,看看是如何访问的

反射概述

有了反射让java变成动态语言

Reflection

反射机制允许在运行期间借用reflection api 取得任何类的内部信息

优点 可以动态创建对象和编译,体现出很大的灵活性

缺点 对性能有影响 使用反射基本上是一种解释操作 告诉jvm要怎么做 ,这样会慢与直接执行的操作

一个类在内存中只有一个class对象

一个类被加载后,整个类的结构都会被封装进一个class对象

通过对象得到类

class类的创建方式

通过对象 getclasss获得

通过Class.forname(“包路径”)获得

通过类名.class获得

基本内置类型都有一个Type方法

Integer.Type()也可以得到一个class

获得父类类型 class.getSuperclass

class有很多方法来使用

所以类型的class对象

几乎所有的类都有

class 外部类,成员,局部内部类,匿名内部类

interface 接口

数组

枚举enum

annotation 注解@interface

基本数据类型

void

只要类型一样就会只有一个class

类加载内存分析

先static静态再执行构造函数

先在方法区设置类的属性,静态方法,常量池,然后生成class文件在堆里面,当一切都完成后开始执行代码。

核心就是 加载 链接 初始化

分析类的初始化

类的主动引用(一定会发生类的初始化)

父类没被加载会先加载父类,再加载子类

反射也会加载主动引用

引用常量不会触发初始化,引用父类不会引起子类的初始化,数组定义类不会引起子类的初始化

类加载器

ext 扩展类加载器

//获取系统类的加载器
ClassLoader systemClassLoader=ClassLoader.getSystemClassLoader();

获取运行时的结构

再得到对象的类后可以用方法得到类的结构

得到类的名称getName

得到类的属性getFields 这个只能得到类的public属性

getDeclaredFields 能找到全部属性

通过反射来获得类的构造器,方法名称属性。

动态创建对象执行方法

有了class对象能做什么

通过反射调用 可以创造类的对象

创造类的对象,使用的是无参构造,需要在类里有无参构造

User user=(User) c1.newInstance()

若想要使用有参构造器创造对象

Constructor constructor=c1.getDeclaredConstructor(String.class,int.class,int.class);//原类代码必须要有参构造
User user2=(User) constructor.newInstance("gg",2,3);
System.out.println(user2.getName());

就是首先设置一个构造器再用newinstance方法。

使用反射调用方法的操作

Method setname=c1.getDeclaredMethod("setName", String.class);
setname.invoke(user3,"guo");

invoke激活,这样就可以使用方法调用

使用反射调用属性

Field name = c1.getDeclaredField("name");//不能直接操作私有属性
name.setAccessible(true);//取消java的安全检验,使反射可以使用私有属性   默认false
name.set(user4,"gagag");

性能对比分析

setAccessible () 启用访问安全检查的开关。

关闭后能提高使用反射的效率

正常方式的性能最好,使用反射会影响效率,在使用反射后关闭安全检查能比不关闭要提高不少效率

获取泛型信息

通过反射去操作泛型

首先什么是泛型

就是指在类定义时不会设置类中的属性或方法参数的具体类型,而是在类使用时(创建对象)再进行类型的定义。

就是类型参数化,参数化类型

获取注解信息

ORM 对象关系映射

都是通过反射来进行的,首先创建一个class类对象,运用方法开始对注解进行分析

首先用getAnnotations可以得到该类的所有注解

Annotation[] annotations=c1.getAnnotations();
for (Annotation annotation : annotations) {
    System.out.println(annotation);
}

得到注解的值

Tablekuang annotation = (Tablekuang)c1.getAnnotation(Tablekuang.class);
System.out.println(annotation.value());

对属性的注解也是一样,先得到属性的class,然后还是getAnnotation,然后输出值

要多加练习。

思考

前面几天个人原因没更新日志,今天又空闲,开始继续学习,把注解和反射学习了,注解就是对程序和人看的注释,起表明的作用,前面有疑问,注解带参数那到底有没有值的传递,现在看确实有的,通过反射学习到,能够通过反射得到注解的值,程序也根据注解的值来判断和匹配相应的位置,反射就是通过程序编译的class文件,然后进行操作,期间学到了内存的问题,说实话还是有点模糊,要多看看计组和操作系统了,学习情况就要算法题,操作系统,计算机组成原理,然后就是框架的学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值