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()方法获得泛型中的参数的类型;

相关推荐
凉、介1 小时前
文件系统(一)——分区表
笔记·学习·嵌入式
今儿敲了吗1 小时前
19| 海底高铁
c++·笔记·学习·算法
Asher阿舍技术站2 小时前
【AI基础学习系列】三、LLM基础知识
人工智能·学习·llm
丝斯20112 小时前
AI学习笔记整理(70)——AI+CAE
人工智能·笔记·学习
三万棵雪松2 小时前
【Linux Shell 编程基础学习与实践作业】
linux·运维·网络·学习·嵌入式linux
会算数的⑨2 小时前
Spring AI Alibaba 学习(三):Graph Workflow 深度解析(下篇)
java·人工智能·分布式·后端·学习·spring·saa
来两个炸鸡腿3 小时前
【Datawhale组队学习202602】Hello-Agents task03 大语言模型基础
人工智能·学习·语言模型·大模型·智能体
CappuccinoRose3 小时前
HTML语法学习文档(三)
前端·学习·html·html5·标签·实体字符
地球空间-技术小鱼3 小时前
搜罗Linux桌面环境(Desktop Environments)列表
linux·运维·服务器·笔记·学习·ubuntu·debian