Java学习日记——DAY24

今天学习了java反射机制的相关知识,学习内容如下:

1.借助于ReflectionAPI实现在程序运行状态过程中,取得任何类的内部信息,在程序运行过程中可以构造任意一个类的对象,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法,这种动态获取程序信息,以及动态调用对象的功能称为java反射机制;

2.java反射机制的功能:

在运行时判断任意一个对象所属的类;

在运行时构造任意一个类的对象;

在运行时查看任意一个类所具有的成员变量和方法;

在运行时调用任意一个对象的方法;

在运行时给任意一个对象的属性赋值;

生产动态代理;

3.Class类:

java在将.class文件载入时,JVM会产生一个Java.lang.Class对象表示该.class字节码文件。class是一个比较特殊的类,是java反射机制的基础。Class类的对象表示正在运行的java程序中的类或接口,Class没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的,因此不能显示创建一个Class类的对象。通过Class对象,才可以获取这个类对象的其他信息,每个类被加载后系统就会生成对应的Class类对象,一旦类被加载到JVM中,同一个类将不会被再次载入;

4.如何获得Class对象:

(1)通过类名.class获得;

(2)通过Class的静态方法forName获得;

(3)通过某个类对象的.getClass()方法获得;

(4)使用类装载器的loadClass()方法获得;

java 复制代码
        //使用class的静态方法forName获得
        Class<?> c1 = Class.forName("demo.Student");
        //使用类名调用class属性来获得
        Class<?> c2 =Student.class;
        //使用该类对象的getClass方法来获得类的对象
        Student student = new Student("小明",12);
        Class<?> c3 = student.getClass();
        //使用类装载器
        ClassLoader classLoader = Student.class.getClassLoader();
        Class<?> c4 = classLoader.loadClass("demo.Student");

5.那些类型可以有Class对象:

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

interface:接口;

数组;

enum 枚举;

annotation:注解;

基本数据类型和void;

6.ClassLoader

java类装载器的作用就是在运行时加载类,基于三个机制

委托机制:将加载一个类的请求交给父类加载器,如果这个父类加载器找不到要加载的类,那么子类再加载他,比如加载一个String类;

可见性机制:子类加载器可以看见所有父类加载器加载的类,但是父类加载器看不到子类加载器加载的类;

单一性机制:加载一个类,仅加载一次,在委托机制中父类已经加载的一个类子类不会再加载了;

加载的两种方式:

显示加载:通过Class.forName()等方法来显示的加载想要的类;

隐式加载:程序在运行过程中,通过new等方法创建对象时,隐式的调用加载器,将其所属类加载到JVM中;

类加载器的分类:

BootStrapClassLoader:根装载器,使用C++编写在Java中看不到他,用于装载核心类库;

ExtClassLoader(PlatformClassLoader):扩展类装载器,装载扩展目录ext中的jar;

AppClassLoader:应用类装载器,负责classpath类的装载;

JVM在装载类的时候使用全盘委托机制,即除了显示的使用一个ClassLoader,不然该类的依赖类以及该类的引用类都将被装载;

JVM在装载类时先将基础类进行装入,再在其他类使用的时候对其装入,这样可以节省内存开销;

7.Constuctor类:

获得Constructor类对象的方法:

java 复制代码
//通过Class类的getDeclaredConstructor()方法获得private和public修饰的构造方法,获得private修饰的构造方法时需要使用setAccessible来设置可访问权限,但是使用getConstructor()方法获得的只能时public方法;
Constructor<?> constructor = Student.class.getDeclaredConstructor();

//通过getParameterTypes()方法获得参数列表数组;
Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();

//通过newInstance获得类实例对象
Object o = constructor.newInstance();

8.Field类:

通过getFields()可以获得类中的所有公有属性和继承自父类的属性;

通过getDeclaredFields()获得该类中的所有属性(含private),不包含继承自父类的属性;

通过getField(属性名)可以获得指定属性(不包含private);

通过getDeclaredField(属性名)可以获得指定属性(包含private,需setAccessible(true));

通过set可以给指定对象设置属性的值;

通过getModifiers方法获得访问修饰符;

9.Method类:

通过getMethods()可以获得类中的所有公有方法和继承自父类的方法;

通过getDeclaredMethods()获得该类中的所有方法(含private),不包含继承自父类的方法;

通过getMethod(方法名,参数类名)可以获得指定方法(不包含private);

通过getDeclaredMethod(属性名)可以获得指定方法(包含private,需setAccessible(true));

通过invoke(对象名,参数列表)可以执行方法,返回值为Object类型;

通过getModifiers方法获得访问修饰符;

10.反射获得泛型:

反射可以获得泛型的场景:

成员变量的泛型;

方法参数的泛型;

方法返回值的泛型;

获取带有泛型的超类或带有泛型的实现的接口;

不能获取局部变量的泛型;

通过调用Method/Field/Class的getGenericType/getGenericParameterTypes/getGenericReturnType...,以返回一个Type类型的对象或数组,可以通过instance方法判断该Type对象是否属于ParameterizedType,如果属于的话可以将其强转为ParameterizedType,再调用getActualTypeArguments()方法获得泛型中的参数的类型;

相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码9 天前
嵌入式学习路线
学习
毛小茛9 天前
计算机系统概论——校验码
学习
babe小鑫9 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms9 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下9 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。9 天前
2026.2.25监控学习
学习
im_AMBER9 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J9 天前
从“Hello World“ 开始 C++
c语言·c++·学习