第7章 Java反射与注解

  • 注解Annotation
    • Annotation的作用
    • Annotation的格式
    • Annotation使用位置
    • 内置注解
    • 元注解
    • 自定义注解
      • 设置后自动生成的注解
  • 2.反射机制
    • 动态语言与静态语言
      • 动态语言
      • 静态语言
      • Java不是动态语言
    • Java反射机制
      • 反射可以获取到private修饰的成员变量和方法
    • 反射的应用
    • Java反射的优缺点
    • 反射的主要API
      • API(Application Programming Interface)
      • 通过对象来获取到它的Class,相当于逆过程。
    • Class本身也是一个类
    • Class类常用的方法
    • 获取对象实例的方法
    • 哪些类型可以有Class对象?
  • 3.Java内存分析
  • JVM(Java Virtual Machine)
  • JRE(java runtime environment)
  • JDK(java development kit)
    • 什么时候发生类初始化
      • 类的主动引用(一定发生初始化)
      • 类的被动引用(不会发生初始化)
    • 类加载的作用
    • 双亲委派机制
    • 反射操作泛型
  • 映射工程
    • ORM(Object relationship Mapping)

注解Annotation

Annotation的作用

不是程序本身,可以对程序做出解释(这一点和注释没有什么区别)
可以被其它程序,比如编译器读取

Annotation的格式

注解以 @注释名 在代码中存在的,还可以添加一些参数值
例如:@SuppressWarnings(value = “unchecked”)

Annotation使用位置

可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息
通过反射机制变成实现对这些元数据的控制

内置注解

@Override:定义在 java.lang.Override中,此注释只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明
实现一个新的方法
加上@Override注解后,表明这个方法可以被覆盖、重写

@Deprecated:定义在java.lang.Deprecated中,此注释可以用于修饰方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险,或者存在更好的选择
@SuppressWarnings:定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息,与前面的两个注释不同,你需要额外添加一个参数才能正确使用,这些参数都是已经定义好了的,我们选择性的使用就好了。
@SuppressWarnings(“all”)
@SuppressWarnings(“unchecked”)
@SuppressWarnings(value={“unchecked”, “deprecation”})

元注解

元注解的作用就是负责注解其它注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其它annotation类型作说明。

这些类型和它们所支持的类在 java.lang.annotation包可以找到
@Target 、@Retention、@Documented、@Inherited

@Target:用于描述注解的使用范围,即:被描述的注解可以在什么地方使用
@Retention:表示需要什么保存该注释信息,用于描述注解的生命周期
级别范围:Source < Class < Runtime
@Document:说明该注解被包含在java doc中 (Java 说明文档)
@Inherited:说明子类可以集成父类中的注解

自定义注解

使用 @interface自定义注解时,自动继承了 java.lang.annotation.Annotation接口

  1. @interface 用来声明一个注解,格式:public @interface 注解名 {定义内容
  2. 其中的每个方法实际上是申明了一个配置参数
  3. 方法的名称j就是参数的类型
  4. 返回值类型就是参数的类型(返回值只能是基本数据类型,Class,String,enum)
  5. 通过default来申明参数的默认值
  6. 如果只有一个参数成员,一般参数名为 value
  7. 注解元素必须要有值,我们定义元素时,经常使用空字符串或者0作为默认值

设置后自动生成的注解

/*** 自定义注解** @author: Larray* @create: 2020-03-28-22:57*/

2.反射机制

动态语言与静态语言

动态语言

动态语言是一类在运行时可以改变其结构的语言:例如新的函数,对象,甚至代码可以被引进,已有的函数可以被删除或是其它结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构

主要的动态语言有:Object-c、C#、JavaScript、PHP、Python等

静态语言

与动态语言相比,运行时结构不可变的语言就是静态语言。例如Java、C、C++

Java不是动态语言

,但是Java可以称为“准动态语言”。即Java有一定的动态性,我们可以利用反射机制来获取类似于动态语言的 特性,Java的动态性让编程的时候更加灵活。

Java反射机制

反射:正常方式的逆过程

什么是反射
Java Reflection:Java反射是Java被视为动态语言的关键,反射机制运行程序在执行期借助于Reflection API 去的任何类内部的信息,并能直接操作任意对象的内部属性及方法。

Class c = Class.forName("java.lang.String")

在加载完类后,在堆内存的方法区就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构,这个对象就像一面镜子,透过这个镜子看到类的结构,所以我们形象的称之为:反射

反射可以获取到private修饰的成员变量和方法

反射的应用

在运行时判断任意一个对象所属类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时获取泛型信息
在运行时调用任意一个对象的成员变量和方法
在运行时候处理注解
生成动态代理

Java反射的优缺点

优点:可以实现动态创建对象和编译,体现出很大的灵活性
缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求,这类操作总是慢于直接执行相同的操作。也就是说new创建和对象,比反射性能更高

反射的主要API

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器

API(Application Programming Interface)

应用程序接口(英语:Application Programming Interface,简称:API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。

/*** 反射Demo** @author: Larry* @create: 2020-03-29-8:21*/
public class ReflectionDemo {public static void main(String[] args) throws ClassNotFoundException {// 通过反射获取类的Class对象Class c1 = Class.forName("com.ctgu.entity.User");Class c2 = Class.forName("com.ctgu.entity.User");Class c3 = Class.forName("com.ctgu.entity.User");System.out.println(c1.hashCode());System.out.println(c2.hashCode());System.out.println(c3.hashCode());}
}

通过对象来获取到它的Class,相当于逆过程。

Class本身也是一个类

Class对象只能由系统建立对象
一个加载的类在JVM中只会有一个Class实例
一个Class对象对应的是一个加载到JVM中的一个.class文件
每个类的实例都会记得自己是由哪个Class实例所生成
通过Class可以完整地得到一个类中所有被加载的结构
Class类是Reflection的根源,针对任何你想动态加载、运行的类、唯有先获得相应的Class对象

Class类常用的方法

ClassforName(String name):返回指定类name的Class对象
newInstance():调用缺省构造函数,返回Class对象的一个实例
getName():返回此Class对象所表示的实体(类,接口,数组或void)的名称
getSuperClass():返回当前Class对象的父类Class对象
getinterfaces():返回当前对象的接口
getClassLoader():返回该类的类加载器
getConstructors():返回一个包含某些Constructor对象的数组
getMethod(String name, Class… T):返回一个Method对象,此对象的形参类型为paramsType
getDeclaredFields():返回Field对象的一个数组

获取对象实例的方法

若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
Class clazz = Person.class;
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz = person.getClass()
已经一个类的全类名,且该类在类路径下,可以通过Class类的静态方法forName()获取,HIA可能抛出ClassNotFoundException
Class clazz = Class.forName(“demo01.Sutdent”)
内置数据类型可以直接通过 类名.Type
还可以利用ClassLoader

哪些类型可以有Class对象?

class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类

interface:接口

[]:数组

enum:枚举

annotation:注解@interface

primitive type:基本数据类型

void

3.Java内存分析

java内存分为以下三部分


存放new的对象和数组
可以被所有的线程共享,不会存放别的对象引用

存放基本变量(会包含这个基本类型的具体数值)
引用对象的变量(会存放这个引用在对堆里面的具体地址)
方法区
可以被所有线程共享
包含了所有的class和static变量

JVM(Java Virtual Machine)

JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。

JRE(java runtime environment)

JRE是java runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib合起来就称为jre。

JDK(java development kit)

JDK是java development kit(java开发工具包)的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。

什么时候发生类初始化

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

当虚拟机启动,先初始化main方法所有在类
new 一个类的对象
调用类的静态成员(除了 final常量)和静态方法
使用 java.lang.reflect包的方法对类进行反射调用
当初始化一个类,如果其父类没有被初始化,则会先初始化它的父类

类的被动引用(不会发生初始化)

当访问一个静态域时,只有真正的申明这个域的类才会被初始化,如:当通过子类引用父类的静态变量,不会导致子类初始化
通过数组定义类引用,不会触发此类的初始化
引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池了)

类加载的作用

类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成了一个代表这个类的 java.lang.Class对象,作为方法区中类数据的访问入口。
类缓存:标准的JavaSE类加载器可以按要求查找类,但是一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象

双亲委派机制

定义一个:java.lang.string 包,无法创建

因为类在加载的时候,会逐级往上

也就是说当前的系统加载器,不会马上的创建该类,而是将该类委派给 扩展类加载器,扩展类加载器在委派为根加载器,然后引导类加载器去看这个类在不在能访问的路径下,发现 string包已经存在了,所以就无法进行,也就是我们无法使用自己自定义的string类,而是使用初始化的stirng类

当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

采用双亲委派的一个好处是比如加载位于rt.jar 包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object 对象

反射操作泛型

Java采用泛型擦除机制来引入泛型,Java中的泛型仅仅是给编译器Java才使用的,确保数据的安全性和免去强制类型转换的问题,但是一旦编译完成后,所有的泛型有关的类型全部被擦除

为了通过反射操作这些类型,Java新增了ParameterizedType,GenericArrayType,TypeVariable和WildcardType几种类型来代表不能被归一到Class类中的类型但是有何原始类型齐名的类型。

ParameterizedType:表示一种参数化类型,比如Collection
GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
TypeVariable:是各种类型变量的公共父接口
WildcardType:代表一种通配符类型的表达式

映射工程

ORM对象关系映射,可实现增删改查的功能

ORM(Object relationship Mapping)

即为:Object relationship Mapping,对象关系映射

类和表结构对应
属性和字段对应
对象和记录对应

第7章 Java反射与注解相关推荐

  1. java反射和注解开发(备java基础,javaee框架原理)-任亮-专题视频课程

    java反射和注解开发(备java基础,javaee框架原理)-5358人已学习 课程介绍         Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明. ...

  2. 第三章. Java反射

    第三章. Java反射 1. 反射 2. 反射接口 2.1获取Class方式: 2.2 获取成员变量并调用 2.3 获取成员方法并调用 2.4 获取构造方法并调用 2.5 获取父类信息 3. 反射应用 ...

  3. java反射获取注解id,通过反射获取注解(Annotation)

    以下实例,定义一个注解.通过反射获取. 主要功能:为所注解过的参数和方法附加一些信息可以获取. 定义注解. import java.lang.annotation.*; @Retention(Rete ...

  4. 注解 java 反射_java注解和反射

    2020-05-19 注解的作用: 不是程序本身,可以对程序做出解释,和注释有相似之处. 可以被其他程序(如编译器)所读取. 注解的格式:以"@注解名"在代码上存在,还可以在其中添 ...

  5. Java反射自定义注解底层设计原理

    文章目录 一.反射 1. 反射概念 2. 反射机制的优缺点 3. 反射的用途 4. 反射技术的使用 5. 反射常用的Api 6. 反射执行构造函数 7. 反射执行给属性赋值 8. 反射执行调用方法 二 ...

  6. java 反射 参数 注解_Java编程之反射中的注解详解

    "注解"这个词,可谓是在Java编程中出镜率比较高,而且也是一个老生常谈的话题.我们之前在聊Spring相关的东西时,注解是无处不在,之前我们简单的聊过一些"注解&quo ...

  7. Java反射+自定义注解实现配置文件数组加载(实现@ConfigurationProperties(xxx))

    Java.Rust 技术交流群: 783303214 一.背景 最近有小朋友问我,怎么样在.properties文件中配置数组参数,我给他举了上篇文章中的注解@ConfigurationPropert ...

  8. Java反射——反射机制问题——第一章

    Java反射--反射机制问题--第一章 Java反射--Class类--第二章 Java反射--类加载--第三章 Java反射--反射获取类的结构信息--第四章 文章目录 1:一个需求引出反射 2:反 ...

  9. 第1章 Java语言概述

    第1章 Java语言概述 声明 0. Java语言应用场景 1. 软件开发介绍 2. 计算机编程语言介绍 3. Java语言概述 4. Java程序运行机制及运行过程 5. Java的环境搭建  5. ...

最新文章

  1. 旷视MegEngine核心技术升级
  2. AI生成中国山水画!普林斯顿姑娘本科毕业作品,骗过70%中国人
  3. JAVA入门笔记·JAVA名词及环境搭建
  4. 【caffe解读】 caffe从数学公式到代码实现2-基础函数类
  5. VTK:突出坏细胞用法实战
  6. python 一行_一行 Python 代码搞定炫酷可视化
  7. Ubuntu10.04制作官方源镜像以及搭建本地源
  8. ArcEngine开发 退出系统报错
  9. 在Ubuntu 13.10 下安装支持SSL的Apache
  10. kido机器人没反应_机器人不能钩的三个英雄,章鱼妈上榜,钩中图四我方直接团灭!...
  11. java 字符界面 curses_[C++]Linux之图形界面编程库[curses库]之入门教程
  12. php十二星座_php计算十二星座的函数代码
  13. 中国甲腈行业市场供需与战略研究报告
  14. 【Shell】获取文件名和扩展名
  15. python怎么恢复默认窗口,如何恢复python编程环境spyder的窗口
  16. MySQL索引实现、MySQL索引原理、索引下推、索引覆盖、索引失效
  17. 信息技术知识点汇总(必修)
  18. 视频播放加密功能的演示
  19. 基于双二阶广义积分器(DSOGI)的软件锁相环需求的根源及s域仿真
  20. 手机--修改dns服务器地址,DNS怎么修改 电脑和手机设置DNS全攻略

热门文章

  1. CAM350技巧【导入gerber文件】【单位尺度设置】【CAM测量】【操作说明与快捷键】【Cam350显示钻孔异常解决】
  2. Buuctf Misc小明的保险箱(暴力破解)
  3. 计算机物质与结构微命令,2015年哈尔滨工程大学082700核科学与技术考研大纲(官方)...
  4. LaTeX数学公式的矩阵、多行公式
  5. MySQL创建索引,各种索引的创建及举例
  6. 通才与专家_成为通才
  7. 具有交叉信号模式的色散信号的群延迟(色散曲线)估计和模式分离(Matlab代码实现)
  8. 好用的Mac虚拟机 Parallels Desktop
  9. 使用PSFTP进行Windows与Linux远程服务器的上传下载
  10. MySQL学习-表记录的查询操作