【JavaSE】反射与模块化

简介: 【JavaSE】反射与模块化

一、类加载器

1、类加载

1)类加载方式

JVM通过类的加载,类的连接,类的初始化对类进行初始化

类的加载:class文件读入内存,创建java.lang.Class对象

2)类的连接

验证:检验类

准备:分配内存,设置默认初始化值

解析:二进制数据中的符号引用替换为直接引用

3)类的初始化

对类变量进行初始化

类没被加载或连接 --> 先加载并连接

父类为初始化 --> 初始化直接父类(最先初始化Object类)

类中有初始化语句 --> 执行初始化语句

2、类的初始化时机

  1. 创建对象,调用方法
  2. 初始化子类
  3. java.exe命令运行主类
  4. 反射创建类或接口的java.lang.Class对象

3、类加载器的作用

将.class加载到内存,生成java.lang.Class对象

4、JVM的类加载机制

全盘负责:加载类及其相关类

父类委托:让父类加载器加载

缓存机制:用过的类有缓存

5、加载器分类

Bootstrap class loader:内置类加载器,通常表示为null

Platform class loader:平台类加载器,加载api、运行时类

System class loader:应用程序类加载器,定义应用程序路径、模块路径

6、ClassLoader类方法

  1. static classLoader getSystemClassLoader():返回用于委派的系统类加载器
  2. ClassLoader getParent():返回父类加载器进行委派

二、反射概述

1、反射

通过类加载器加载的.class文件对象的Class类进行调用

反射是框架设计的灵魂

框架:半成品软件。可以在框架基础上进行软件开发,简化编码

2、反射机制

将类的各个组成部分封装成其他对象

3、反射优点

  1. 可以在程序运行中操作对象 idea
  2. 可以解耦,提高程序可扩展性

4、Java代码的三个阶段

  1. Source源代码:.java ->(javac编译) .class
  2. Class类对象:*.class ->(ClassLoader类加载器) class类对象
  3. Runtime运行阶段:创建对象

三、获取class对象的方式

1、Class.forName()

Source源代码阶段:Class.forName("包名.类名");

Class类的静态方法

将字节码文件加载进内存,返回class对象

2、类名.class

Class类对象阶段:类名.class

通过类名的属性返回class对象

3、对象.getClass()

Runtime运行阶段:对象.getClass()

定义在Object类中

同一个字节码文件(*.class)在一次程序运行中只会加载一次

四、Class对象功能

1、获取成员方法

Field[] getFields()                    //获取所有public修饰成员
File getField(String name)            //获取指定名称public修饰成员

Field[] getDeclaredFields()            //获取所有的成员
File getDeclaredField(String name)    //获取指定名称的成员

Field成员变量:

  1. 设置值:void set(Object obj, Object value)
  2. 获取值:get(Object obj)

暴力反射(忽略权限修饰符的安全检查):变量对象.setAccessible(true);

2、获取构造方法

Constructor<?>[] getConstructor()
Constructor<T> getConstructor(<?>... parameterTypes)    //指定构造方法的参数 String.class int.class ...

Constructor<?>[] getDeclaredConstructor()
Constructor<T> getDeclaredConstructor(<?>... parameterTypes)

Constructor构造方法:Object obj = 构造方法对象.newInstance(构造)

3、获取成员方法

Method[] getMethods()
Method getMethods(String name,<?>... parameterTypes

Method[] getDeclaredMethods()
Method getDeclaredMethods(String name,<?>... parameterTypes)

Method方法对象:

  1. 执行方法:方法对象.invoke(Object obj, Object...args);
  2. 获取方法名:String getname()

4、获取类名

String getName()

五、越过泛型检查

List<Integer> list = new ArrayList<>();
list.add(123);
Method m = list.getClass().getMethod("add", Object.class);
m.invoke(list,"hello");
System.out.println(list);

六、运行配置文件的指定方法

className=...
methodName=...
Properties prop = new Properties();
prop.load(new FileReader("xxx.txt"));
Class<?> c = Class.forName(prop.getProperty("className"));
Method m =c.getMethod(prop.getProperty("methodName"));
Object obj = c.newInstance();
m.invoke(obj);

七、模块化使用

Java9推出模块化

  1. 在模块的scr目录下新建module-info.java的描述文件
  2. 对于导出模块:exports 包名;
  3. 对于导入模块:requires 包名;

八、模块服务的使用

1、导出模块

描述文件:provides 接口名 with 实现类

2、导入模块

1、描述文件:uses 接口名

2、加载服务:ServiceLoader<接口名> 变量名 = ServiceLoader.Load(导出模块名.class);

3、遍历服务:

for(接口名 变量名2 : 变量名){
   
    变量名2.接口内的方法();    // 实现其模块实现类的方法
}
目录
相关文章
|
1天前
|
Java 编译器 API
JavaSE基础篇:反射(二)
JavaSE基础篇:反射(二)
|
8月前
|
Java 程序员
【javaSE】 面向对象程序三大特性之继承(一)
【javaSE】 面向对象程序三大特性之继承(一)
|
8月前
|
Java 编译器
【javaSE】 面向对象程序三大特性之继承(二)
【javaSE】 面向对象程序三大特性之继承(二)
|
8月前
|
存储 Java 编译器
【javaSE】面向对象程序三大特性之封装(二)
【javaSE】面向对象程序三大特性之封装(二)
|
8月前
|
Java 编译器
【javaSE】面向对象程序三大特性之封装(一)
【javaSE】面向对象程序三大特性之封装(一)
|
8月前
|
存储 Java 数据库
【JAVASE】封装 下
【JAVASE】封装
|
Java API Maven
Java工具篇之反射框架Reflections
Reflections通过扫描classpath,索引元数据,并且允许在运行时查询这些元数据。 使用Reflections可以很轻松的获取以下元数据信息: - [x] 获取某个类型的全部子类 - [x] 只要类型、构造器、方法,字段上带有特定注解,便能获取带有这个注解的全部信息(类型、构造器、方法,字段) - [x] 获取所有能匹配某个正则表达式的资源 - [x] 获取所有带有特定签名的方法,包括参数,参数注解,返回类型 - [x] 获取所有方法的名字 - [x] 获取代码里所有字段、方法名、构造器的使用权
1219 0
|
1天前
|
存储 设计模式 安全
JavaSE基础篇:反射(一)
JavaSE基础篇:反射(一)
JavaSE基础篇:反射(一)
|
5月前
|
Java 程序员
【JavaSE】面向对象之封装
【JavaSE】面向对象之封装
|
5月前
|
Java 程序员 编译器
【JavaSE】面向对象之继承
【JavaSE】面向对象之继承