java学习(二):反射

系列文章目录

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.mzph.cn/news/5794.shtml

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

相关文章

代码随想录-回溯(组合问题)|ACM模式

目录 前言&#xff1a; 77.组合 题目描述&#xff1a; 输入输出示例&#xff1a; 思路和想法&#xff1a; 216. 组合总和 III 题目描述&#xff1a; 输入输出示例&#xff1a; 思路和想法&#xff1a; 17. 电话号码的字母组合 题目描述&#xff1a; 输入输出描述&a…

MyBatis的多表操作

1 MyBatis的多表操作 1.1 多表模型介绍 我们之前学习的都是基于单表操作的&#xff0c;而实际开发中&#xff0c;随着业务难度的加深&#xff0c;肯定需要多表操作的。 多表模型分类 一对一&#xff1a;在任意一方建立外键&#xff0c;关联对方的主键。 一对多&#xff1a;在…

实用便捷!一站式BI系统推荐

在企业数字化转型过程中&#xff0c;BI系统可以建立业务、数据的双驱引擎&#xff0c;形成业务、数据的互补作用&#xff0c;通过建立数字化技术架构&#xff0c;明确企业的战略定位和业务目标&#xff0c;从而支撑实现这个目标。而一站式BI系统&#xff0c;则是指可以轻松从数…

【MySQL】SQL性能分析 (七)

&#x1f697;MySQL学习第七站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 假如我们需要对SQL进行优化&#xff0c;我们就必须对他足够的了解&#xff0c;比如 对哪一类SQL进行优化&#xff08;增删改查…

基于物联网网关的工业数据可视化平台有什么功能?

随着数字化浪潮的不断发展&#xff0c;工业数据的价值越来越重要。在企业利用数据的过程中&#xff0c;数据可视化是数字化系统中十分重要的一部分。然而&#xff0c;工厂多种设备、多种协议影响到系统的搭建使得企业无法获得全面的数据视图&#xff0c;也无法对整个生产流程进…

OJ练习第142题——路径总和 II

113. 路径总和 II 力扣链接&#xff1a;113. 路径总和 II 题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 Java代码&#xff08;深度优先搜…

六边形架构

六边形架构 微服务系统架构微服务定义微服务系统设计 传统分层架构六边形架构参考资料 微服务系统架构 需求描述做什么的问题&#xff0c;架构描述怎么做的问题(描述组成系统的各部件及其之间的关系) 微服务定义 下面的定义来自周志明老师的 凤凰架构 微服务是一种通过多个小型…

【Linux】 由“进程”过渡到“线程” -- 什么是线程(thread)?

知识引入初识线程1.什么叫做进程&#xff1f;2.什么叫做线程&#xff1f;3.如何看待我们之前学习的进程&#xff1f; 理解线程创建线程函数调用1.线程一旦被创建&#xff0c;几乎所有资源都是被线程所共享的2.与进程之间切换相比&#xff0c;线程的切换 初识线程总结&#xff1…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

操作系统练习:进程间通信(共享内存方式)

说明 本文是《操作系统概念(第九版)》3.4节“进程间通信”的练习。 进程间通信主要由两种模型&#xff1a; 共享内存消息传递 本文使用共享内存的方式实现进程间的通信 创建消息生产者 创建生产者的主要操作包括&#xff1a; 定义共享内存的大小、名称&#xff0c;以及通…

netty知识集锦2

粘包半包 粘包半包解决方案&#xff0c; 1短链接&#xff0c;它的消息边界是从链接建立到链接断开 2.定长解码器&#xff1a;服务器端选最大长度的消息作为定长&#xff0c;客户端不足补齐&#xff0c;缺点造成浪费 netty协议设计与解析 Message编码解码

AWS IAM介绍

前言 AWS是世界上最大的云服务提供商&#xff0c;它提供了很多组件供消费者使用&#xff0c;其中进行访问控制的组件叫做IAM(Identity and Access Management)&#xff0c; 用来进行身份验证和对AWS资源的访问控制。 功能 IAM的功能总结来看&#xff0c;主要分两种&#xff1…

《零基础入门学习Python》第060讲:论一只爬虫的自我修养8:正则表达式4

有了前面几节课的准备&#xff0c;我们这一次终于可以真刀真枪的干一场大的了&#xff0c;但是呢&#xff0c;在进行实战之前&#xff0c;我们还要讲讲正则表达式的实用方法和扩展语法&#xff0c;然后再来实战&#xff0c;大家多把持一会啊。 我们先来翻一下文档&#xff1a;…

openGauss学习笔记-17 openGauss 简单数据管理-表达式

文章目录 openGauss学习笔记-17 openGauss 简单数据管理-表达式17.1 简单表达式17.2 条件表达式17.3 子查询表达式17.4 数组表达式17.5 行表达式 openGauss学习笔记-17 openGauss 简单数据管理-表达式 表达式类似一个公式&#xff0c;我们可以将其应用在查询语句中&#xff0c…

25 MFC 数据库

文章目录 导入ADO库 导入ADO库 #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")void CADODlg::OnBnClickedBtnQuery() {//导入ADO库::CoInitialize(NULL);//初始化COM库_ConnectionPtr pCo…

《面试1v1》如何提高远程用户的吞吐量

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Flutter动画库:animations(路由过渡动画或者页面切换动画)

animations animations 是一个 Flutter 库&#xff0c;它提供了一组用于创建动画效果的工具和组件。这个库的核心重点是路由过渡动画或者页面切换动画 地址 https://pub-web.flutter-io.cn/packages/animations 安装 flutter pub add animations看了下官方文档和官方例子&a…

计科web常见错误排错【HTTP状态404、导航栏无法点开、字符乱码及前后端数据传输呈现、jsp填写的数据传到数据库显示null、HTTP状态500】

web排错记录 在使用javaweb的过程中会出现的一些错误请在下方目录查找。 目录 错误1&#xff1a;HTTP状态404——未找到 错误2&#xff1a;导航栏下拉菜单无法点开的问题 错误3&#xff1a;字符乱码问题 错误4&#xff1a;jsp网页全部都是&#xff1f;&#xff1f;&#x…

【单片机】MSP430F149单片机,晨启,音乐播放器,蜂鸣器音乐

四、音乐播放器 任务要求&#xff1a; 设计制作一个简易音乐播放器&#xff08;通过手柄板上的蜂鸣器发声&#xff0c;播放2到4首音 乐&#xff09;&#xff0c;同时LED模块闪烁&#xff0c;给人视、听觉美的感受。 评分细则&#xff1a; 按下播放按键P15开始播放音乐&#x…

【C++】继承基础知识及简单应用,使用reportSingleClassLayout(在Visual Studio开发人员命令提示窗口)查看派生类详细信息

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】继承基础知识及简单应用&#xff0c;使用reportSingleClassLayout&#xff08;在Visual Studio开发人员命令提示窗口&#xff09;查看派生类详细信息 website&#xff1a;黑马程序员C date&#xf…