java学习(二):反射

news2024/11/26 23:24:02

系列文章目录

https://editor.csdn.net/md/?articleId=131757340

文章目录

  • 系列文章目录
  • 参考
  • 【1】注解
    • 1. 什么是注解
    • 2. 内置注解
    • 3. 元注解
    • 4.自定义注解
  • 【2】反射--基本概念
  • 一、反射的基本概念
    • 1. 为什么要用反射?
    • 2. 什么是反射?
    • 3. 用和不用反射的区别?
    • 4.开发中什么场景下用反射?
    • 5.反射优点和缺点:
  • 二、反射的使用
    • 1. 获取反射对象的4种方式
    • 2.哪些类型哟class对象?
  • 三、类加载过程
    • 1.加载过程
    • 2. 补充:java 内存分析
    • 3. 类加载器 + 类的双亲委派机制
    • 4. 怎么获取类运行过程中的各种对象(方法、参数、构造器等)
    • 5. 用class对象能怎么用?
    • 6.应用:反射的动态性:


参考

可以参考的笔记: https://blog.csdn.net/ProGram_Java521/article/details/127733167
学习视频:
https://www.bilibili.com/video/BV1PY411e7J6?p=192&vd_source=585eef59d366645f5bf03840b1010547
https://www.bilibili.com/video/BV1p4411P7V3/?spm_id_from=333.337.search-card.all.click

【1】注解

1. 什么是注解

–对程序作出解释。@注释名”在代码中存在的,还可以添加一些参数值
注解在哪里使用?–可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制实现对这些元数据的访问

2. 内置注解

@Override @Deprecated等

3. 元注解

负责注解其他的注解。通过4个元注解说明其他注解的作用域、作用方式等。
@Target :描述作用范围
@Retention :描述注解的生命周期(源码、类、runtime运行时)
@Document :包含再javadoc中
@Ingerited :自雷可以继承父类中的注解

4.自定义注解

设置作用域、返回类型等可以借助元注解

【2】反射–基本概念

一、反射的基本概念

1. 为什么要用反射?

1)java程序中的两种对象类型,编译时类型 和 运行时类型。如果出现编译时类型和运行时类型不一致,要怎么解决?
2)如果已知运行时类型,可以用instanceof 直接判断。
3)无法预知运行时类型,只能依靠运行时的信息获取对象和类的真实信息 --由此引入反射机制。

2. 什么是反射?

在代码运行过程中,允许程序借助Reflection API取得类的任何内部信息、操作类的属性和方法。
作用:操作字节码

正常方式: 引入包类 --》new 实例化对象 --》 取得实例化对象
反射方式: 实例化对象 --》getClass()方法 --》得到完整的“包类”名称

3. 用和不用反射的区别?

不用反射,出了类之后,private属性和方法不能使用–类的封装性
使用反射:可以访问私有方法属性

4.开发中什么场景下用反射?

1)一般业务开发,对使用对象已知和确定,基本可以不用反射
2)对于框架的开发,体现动态性,考虑使用反射。

5.反射优点和缺点:

优点:自适应 灵活 动态获取
缺点:性能较差。

二、反射的使用

1. 获取反射对象的4种方式

CLass.forName(“完整包名”)
对象.getClass()
任何类型.class
ClassLoader.getSystemClassLoader().loadClass(“完整包名”)
基本数据类型 Integer.TYPE

2.哪些类型哟class对象?

class
interface
数组
enum
annotation 注解
基本数据类型
void

三、类加载过程

1.加载过程

·过程1:类的装载(Loading)
把class文件读入内存,并创建一个java.lamg.Class对象,由类加载器完成

·过程2:链接(linking)

验证(verify):确保类加载嘻嘻符合JVM规范。比如,cafebabe
准备(prepare):给static变量分配内存并且设置初始值。这里的内存都在方法区中分配
解析(Resolve):虚拟机常量池内的符号引用(常量名)替换为直接引用(引用地址)

·过程3:初始化(initialization)
执行类构造器方法。

2. 补充:java 内存分析

堆:存new的对象和数组,可以被所有线程共享
栈:存基本变量类型、引用类型的变量(存引用在堆里的具体地址)
方法区:所有class和static变量,被所有线程共享

3. 类加载器 + 类的双亲委派机制

4. 怎么获取类运行过程中的各种对象(方法、参数、构造器等)

常用的API 接口

5. 用class对象能怎么用?

动态创建对象:
1)newInstance 对无参构造函数创建对象
2)getDeclaredConstructor 先获取构造器,在用构造器创建对象。
3)执行方法 getMethod,用invoke进行调用的激活
4)私有属性 方法可以用setAccessible(true); // 关掉权限检测

6.应用:反射的动态性:

在这里插入图片描述

package com.common.inject;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class ReflectTest {
    // 举例1:反射的动态性--类
    public <T> T getInstance(String className) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class c1 = Class.forName(className);

        Constructor con = c1.getDeclaredConstructor();
        con.setAccessible(true);
        return (T) con.newInstance();
    }

    // 举例2:反射的动态性--方法
    public static Object invoke(String className, String methodName) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1.创建雷鸣对应的运行时的类对象
        Class c1 = Class.forName(className);
        Constructor con = c1.getDeclaredConstructor();
        con.setAccessible(true);
        Object o = con.newInstance();
        
        //2. 获取运行时类中的方法
        Method method = c1.getDeclaredMethod(methodName);
        method.setAccessible(true);
     return method.invoke(o);

    }

    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        String className ="com.common.inject.LearnInject";
        String methodName = "del";
        System.out.println(invoke(className, methodName));
    }
}
public class LearnInject {
    private int id;

    public LearnInject() {
    }

    public LearnInject(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int add(int a, int b) {
        return a + b;
    }
    private String del() {

        return "This is del method";
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {



        Class c1 = Class.forName("com.common.inject.LearnInject");

        Class c0 = ClassLoader.getSystemClassLoader()
                .loadClass("com.common.inject.LearnInject");

        System.out.println(c1 == c0);
        // 创建实例对象:构造器
//        LearnInject l1 = (LearnInject)c1.newInstance();
//        System.out.println(l1);

        Constructor constructor = c1.getDeclaredConstructor(int.class, String.class);
        LearnInject l2 = (LearnInject)constructor.newInstance(1, "one");
        System.out.println(l2.toString());

        System.out.println(l2.add(1, 2));

        // 通过反射调用方法
        LearnInject l3 = (LearnInject) c1.newInstance();

        Method add = c1.getDeclaredMethod("add",int.class,int.class);
        int invoke = (int) add.invoke(l3, 1, 2);
        System.out.println(invoke);

        Field id = c1.getDeclaredField("id");
        id.setAccessible(true); // 关掉权限检测
        id.set(l3, 10);
        System.out.println(l3.id);


//        Class c1 = Class.forName("com.common.inject.LearnInject");
//        System.out.println(c1);
//        System.out.println(c1.hashCode());
//
//        System.out.println(c1);
//        // 获取类运行过程中的对象
//        System.out.println(c1.getName());
//        System.out.println(c1.getClassLoader());
//        System.out.println(c1.getField("name")); // getField获取public
//        System.out.println(c1.getDeclaredField("id"));  // getDeclaredField获取所有的变量
//
//
//        Method[] methods = c1.getMethods();  // getMethods 获取本类和父类的所有public方法
//        for (Method method : methods) {
//            System.out.println("getMethods:" + method);
//        }
//
//
//        methods = c1.getDeclaredMethods(); // getDeclaredMethods 获取本类的所有方法
//        for (Method method : methods) {
//            System.out.println("getDeclaredMethods:"  + method);
//        }
//
//        System.out.println(c1.getMethod("add", int.class, int.class));
//
//        LearnInject learnInject = new LearnInject();
//        Class c2 = learnInject.getClass();
//        System.out.println(c2);
//
//        System.out.println(c2.hashCode());
//
//        Class c3 = LearnInject.class;
//        System.out.println(c3);
//        System.out.println(c3.hashCode());
//
//        // 内置基本类型可以用类名.Type
//        Class<Integer> type = Integer.TYPE;
//        System.out.println(type.hashCode());
//
//        Integer val = new Integer(1);
//        System.out.println(val.getClass().hashCode());


    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/782001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring复习:(49)@Configuration配置类上的注解是在哪里被解析的?

主类示例源代码如下&#xff1a; 配置类源码如下&#xff1a; 进入context.register方法&#xff1a; 进入this.reader.register方法&#xff1a; 进入registerBean方法&#xff1a; 进入doRegisterBean方法&#xff1a; 进入AnnotatedGenericBeanDefinition构造方法&am…

计算机科学cs/电子信息ei面试准备——python复习|理解题|简答题

目录 1 请简要概述python技术的主要应用场景? 2 python的基本数据类型是那几种? 3 python数组和列表有什么区别? 4 Python中的函数是什么&#xff1f; 5 请写出删除列表中的元素有几种方式? 6 描述python函数中递归的理解? 7 请介绍join()和split()的区别? 8 介绍…

C++ - 初识vector类 迭代器失效

之前对C当中的string类做了了解和模拟实现&#xff1a; C-string类的模拟实现_chihiro1122的博客-CSDN博客 C string类-2_chihiro1122的博客-CSDN博客 C string类 迭代器 范围for_string类型迭代器_chihiro1122的博客-CSDN博客 vector类使用模版来实现了&#xff0c;我们可…

如何在APP开发中实现无缝用户体验?

我们在日常生活中经常会看到这样一种情况&#xff1a;当我们打开 APP时&#xff0c;有时会出现卡顿、死机的情况&#xff0c;这就是所谓的“死机”现象。在开发 APP时&#xff0c;我们需要考虑用户体验&#xff0c;在用户操作 APP时能够感受到顺畅的使用体验&#xff0c;让用户…

设计模式—1、23种设计模式详解

目录 一、设计模式概述 二、设计模式的分类&#xff08;总共有 25 种设计模式&#xff09; 1、创建型模式&#xff08;5种&#xff09; 2、结构型模式&#xff08;8种&#xff09; 3、行为型模式&#xff08;12种&#xff09; 三、设计模式的优点和缺点 1、设计模式的优点…

Android OpenGL 教程——Native 工程初始化

NativeActivity NDK 的适用场景官方给出三点&#xff1a; 平台间的 App 移植复用现有库对软件性能要求较高的场合比如游戏等 有两种方式可以实现 native activity。 native_activity.handroid_native_app_glue 由于第二种方法启用另一个线程处理回调和输入事件&#xff0c…

用 Generative AI 构建企业专属的用户助手机器人

原文来源&#xff1a; https://tidb.net/blog/a9cdb8ec 关于作者&#xff1a;李粒&#xff0c;PingCAP PM TL;DR 本文介绍了如何用 Generative AI 构建一个使用企业专属知识库的用户助手机器人。除了使用业界常用的基于知识库的回答方法外&#xff0c;还尝试使用模型在 fe…

QML使用滚轮/触控板实现水平滚动/垂直滚动/缩放功能

目录 引言核心代码完整代码 引言 因为项目需要需要进行组件移动、缩放的开发&#xff0c;具体要求如下&#xff1a; 鼠标滚轮&#xff0c;实现垂直移动Ctrl鼠标滚轮&#xff0c;实现缩放Alt鼠标滚轮&#xff0c;实现水平移动触控板移动&#xff0c;实现垂直、水平移动触控板双…

C#事件学习笔记

一.事件概述&#xff1a; 事件的作用是降低模块间的耦合度&#xff0c;本质是观察者模式的应用&#xff0c;通过增加监听器&#xff0c;使事件响应函数的调用分散在各个对象自身内部&#xff0c;当增加和减少一个事件响应函数时&#xff0c;只需要增加或删除相应对象内的代码&…

MyBatis-Plus 的基础增删改查

目录 1. 简介 2. 准备工作 3. MyBatis-Plus 实现增删改查 1. MyBatis-Plus 简介 MyBatis-Plus&#xff08;简称 MP&#xff09;是 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生. 2. 准备工作 2.1 准备数据表 D…

ArgoCD结合Gitlab交付项目到kubernetes集群

ArgoCD结合Gitlab交付项目到kubernetes集群 作者:行癫(盗版必究) 一:环境准备 1.kubernetes集群环境 2.HA_Argocd环境 3.Gitlab集群环境 二:项目配置 1.配置Gitlab 创建仓库,并写入yaml文件,利用yaml构建application;此案例结合了NFS实现持久化存储

【ARM Coresight 系列文章 10.2 - ARM Coresight STM Trace packets】

文章目录 Trace protocolpacket的种类Error packetsVERSION Packets同步 packet 上篇文章&#xff1a;ARM Coresight 系列文章 10.1 - ARM Coresight STM 介绍及使用 Trace protocol STM 产生的trace的是遵守 MIPI System Trace Protocol version 2 (STPv2) 规范的&#xff0c…

Windows环境下Elasticsearch相关软件安装

Windows环境下Elasticsearch相关软件安装 本文将介绍在 windows 环境下安装 Elasticsearch 相关的软件。 1、安装Elasticsearch 1.1 安装jdk ElasticSearch是基于lucence开发的&#xff0c;也就是运行需要java jdk支持&#xff0c;所以要先安装JAVA环境。 由于ElasticSear…

【C++】深入剖析list

本期我们来深入list的实现原理&#xff1a; 目录 一、STL中的list 二、list的模拟实现 2.1 搭建list的框架 2.2 list迭代器的实现 2.2.1 普通迭代器的实现 2.2.2 const类型迭代器的实现 2.2.3 迭代器中->运算符重载实现 2.3 其他功能函数的实现 2.3.1 insert 2.…

爬虫小白-如何辨别是否有cookie反爬案例

目录 一、Cookie介绍二、cookie生成来源区分查找三、如何判断是否有cookie反爬四、来自服务器生成的cookie反爬解决方法五、来自js生成的cookie反爬解决方法 一、Cookie介绍 先推荐该篇文章简单了解Cookie、Session、Token、JWT1、cookie的类型&#xff1a;会话cookie和持久co…

【LeetCode热题100】打卡第42天:滑动窗口最大值搜索二维矩阵II

文章目录 【LeetCode热题100】打卡第42天&#xff1a;滑动窗口最大值&搜索二维矩阵II⛅前言 滑动窗口最大值&#x1f512;题目&#x1f511;题解 搜索二维矩阵II&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第42天&#xff1a;滑动窗口最大值&搜索二维…

装箱问题(背包问题)

题目描述 有一个箱子容量为v(正整数&#xff0c;o≤v≤20000)&#xff0c;同时有n个物品(o≤n≤30)&#xff0c;每个物品有一个体积 (正整数)。要求从 n 个物品中&#xff0c;任取若干个装入箱内&#xff0c;使箱子的剩余空间为最小。 输入格式 第一行&#xff0c;一个整…

js函数增强

目录 函数的属性arguments将arguments转换成数组rest 纯函数柯里化函数自动实现函数柯里化组合函数自动实现组合化with与evalwitheval 严格模式严格模式的限制 函数的属性 函数其实也是一个对象 是对象就会有对应的方法与属性 以下是几个常用属性 name name属性主要用于访问给…

vue 富文本图片回显

富文本上传 <el-form-item label"服务费打款银行回单" prop"bankreceipt"> <!-- <ImageUpload--> <!-- :value"form.bankreceiptUrl"--> <!-- :fileType"fileType"--> <…

【解决方案】视频传输方案怎样选择适用的WiFi模块

工作环境中&#xff0c;我们接触的最多的是有线传输&#xff0c;但是这个会因为转换接口、传输距离等原因受到一些限制&#xff0c;而无线传输不会&#xff0c;不需要布线&#xff0c;不限制接口&#xff0c;传输距离也由于有线传输&#xff0c;这也是物联网广泛使用无线通信技…