JavaEE初阶---properties类+反射+注解

文章目录

  • 1.配置文件properities
  • 2.快速上手
  • 3.常见方法
    • 3.1读取配置文件
    • 3.2获取k-v值
    • 3.3修改k-v值
    • 3.4unicode的说明
  • 4.反射的引入
    • 4.1传统写法
    • 4.2反射的写法(初识)
    • 4.3反射的介绍
    • 4.4获得class类的方法
    • 4.5所有类型的class对象
    • 4.6类加载过程
    • 4.7类初始化的过程
    • 4.8类加载过程
    • 4.9获取类的运行时结构
    • 4.10动态创建对象
    • 4.11获取成员属性方法
    • 4.12性能测试
  • 5.反射的应用
    • 5.1操作泛型
    • 5.2操作注解
  • 6.注解annotation
    • 6.1内置注解
    • 6.2元注解
    • 6.3自定义注解
    • 6.3自定义注解

1.配置文件properities

这个properity是一个类:方便实现对于这个项目的相关的属性内容的设置;

例如我们想要使用这个程序对于这个数据库进行操作,我们的这个程序本来是针对于这个数据库01进行操作的,后来修改为这个对于02进行操作,如果我们没有使用这个配置文件,就需要在这个源码上面进行修改,这个不是我们想要看到的,如果我们引入了这个配置文件;

这个时候因为我们的这个程序是从这个配置文件里面读取内容的,因此这个程序的代码不需要进行修改,我们只需要把这个配置文件的这个用户名和密码修改为我们的db02数据库的就可以了;
image-20241109140758037

2.快速上手

下面的这个就是我们的一个包包里面的配置文件:这个配置文件里面的信息就是我们的ip,用户名和密码;

image-20241109141730790

我们在这个java文件里面,需要创建对象读取这个配置文件里面的内容,这个就涉及到了这个路径的指定,是从我们的这个src开始的,根据我们的这个目录结构进行修改即可;

然后我们使用这个while循环不断的从这个对象里面进行内容的读取,这个就会全部打印输出;

image-20241109141509379

在上面的这个方式下,我们的打印输出的结果就是我们的这个配置文件里面的格式:

image-20241109142225711

下面的这个就是另外一个打印输出的方法的展示:就是我们不是直接把这个配置文件里面的信息打印出来,而是按照我们想要的这个格式,使用这个split进行分割处理,进行拼接之后再打印出来;(这个刚开始的时候遇到了bug,就是因为这个配置文件每一行之间加上了空格,这样的话督导第二行没有了然后这个split[1]这个下标就会报错是越界,因此上面的这个配置文件里面的这个内容需进行修改为连续的三行,否则会报错);

image-20241109142732918

但是即使这样,我们想要修改这个文件的用户名和方法还是不容易;因为这个需要我们的代码进行修改;

3.常见方法

image-20241109143257557

3.1读取配置文件

我们首先需要创建一个类,读取我们的这个配置文件内容(new filereader里面的这个参数就是我们的这个配置文件的地址);

最后使用这个list方法把我们的这个读取的文件里面的内容打印到我们的这个对应的设备上面去;

image-20241109144343933

3.2获取k-v值

在上面的这个基础上,我们可以使用这个getProperty方法,根据我们传递进去这个key参数,获得这个对应的value值,这个就是我们根据这个k获取到这个对应的value的一个方法;

image-20241109144503923

3.3修改k-v值

这个表面上写的是修改,实际上是包含了这个添加新的这个k-v的情况的:

我们调用这个里面的serProperties方法对于这个key对应的value进行修改,如果这个key是存在的,这个就是修改对应的value数值;

如果这个key不存在,下面的这个password2就是不存在的,这个时候就是进行新的k-v的添加;

store表示把这个创建的对象存储到我们的这个配置文件里面去,第一个参数就是我们的路径,第二个参数写的是comment(这个是idea自带的)表示的就是注释的意思,我们使用null代替就可以了;

image-20241109145128983

3.4unicode的说明

我们上面修改这个名字是中文,这个时候我们的这个配置文件里面显示的其实是这个unicode编码,并不是我们的中文,我们可以使用这个转换器进行查看结果是否正确;

image-20241109145519957

我们使用这个转换工具就可以看到这个效果:

image-20241109145543119

4.反射的引入

4.1传统写法

我们的这个反射是需要基于上面的这个类的,因此上面相当于就是介绍一下这个类的相关的用法;

image-20241109152943544

下面的是是两个传统方法:

1)直接创建对象,调用这个对象里面的方法;

2)使用文件流读取,获取这个对应的value数值,并且打印出来;

image-20241109153133782

4.2反射的写法(初识)

image-20241109163349454

4.3反射的介绍

image-20241110102054430

下面的这个就是我们自己定义一个实体类:

image-20241110102558259

4.4获得class类的方法

image-20241110103856617

4.5所有类型的class对象

image-20241110104424698

2)元素类型一样,例如这个数组,个数不一样,但是这个类型一样,他们的这个class打印出来的这个hashcode还是一样的;

4.6类加载过程

image-20241110105334192

上面的这个类加载的过程,分为三个步骤:

1)加载:就是生成在这个相关的数据,每一个类里面都是有自己的这个数据的;

2)链接:每一个类生成自己的这个Class对象,进行连接就是检查是不是有错误;

3)初始化:没有错误就会进行初始化,刚开始这个m初始化的是0.然后我们创建这个对象,这个对象就会找到自己的这个类对象,进行这个合并,刚开始是300,后来是100,因此这个最后打印输出的这个结果就是100;

image-20241110105425269

4.7类初始化的过程

1)主动引用一定会发生这个类的初始化:下面的这个new对象和反射就是主动引用的过程;

2)被动引用不会进行类的初始化:下面的这个直接调用子类的这个静态变量,创建数组,以及常量的使用都是属于这个被动引用的范畴的,都是不会执行这个初始化的操作的;

image-20241110110803197

4.8类加载过程

1)类加载的作用:把class文件的字节码的内容加载到我们的这个内存里面去,在这个堆区上面生成一个Class对象,这个对象就是我们的访问入口;

2)类缓存:一旦某一个类加载到了这个类加载器里面去,他就会维持一段时间,不过这个JVM的垃圾回收机制会对于这个Class对象进行处理;

image-20241110111010382

4.9获取类的运行时结构

1)field就是获取这个类加载的时候的相关的属性,加上这个declare修饰就是强制获取,第一个只能获取到这个公共的方法,但是我们加上这个declare修饰之后即使是私有的方法,我们也是可以获取到的;

image-20241110112810041

4.10动态创建对象

下面的这个就是需要有我们的无参数的构造器:

image-20241110123525801

上面的这个是需要我们的这个类里面有无参数的构造方法,如果这个无参数的构造方法没有了,这个时候就会报错,下面的这个就是在原来的这个基础上面,我们自己写一个构造器出来,这样无论是有参数无参数,我们自己写的这个构造器都是可以传参的;

我们的这个构造器里面的参数就是我们的三个成员变量,我们创建对象的时候,就是用我们的这个构造器;

image-20241110123941187

4.11获取成员属性方法

下面的这个就是我们使用无参数的构造器创建对象,setAccessible表示的就是关闭安全检查,即使我们的这个name是私有的,我们使用这个declared版本的还是可以得到的;

set相当于就是传递参数,第一个就是我们的这个对象,第二个参数就是这个对象的属性name具体值;

image-20241110140725978

4.12性能测试

下面的这个是三个不同的方式的一个效率的对比:

1)test01就是普通方法;

2)test02就是反射,但是不关闭这个检测;

3)test03就是2的基础上面关闭这个检测的机制;

可以在自己的这个IDEA上面运行感受一下这个时间的耗费;

public class Test {public static void test01 () {User user = new User();long startTime = System.currentTimeMillis();for (int i = 0; i < 100000000; i++) {user.getName();}long endTime = System.currentTimeMillis();System.out.println("正常运行"+(endTime - startTime)+"ms");}public static void test02 () throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User user = new User();Class c1=user.getClass();Method getName = c1.getDeclaredMethod("getName",null);//getName.setAccessible(true);long startTime = System.currentTimeMillis();for (int i = 0; i < 100000000; i++) {getName.invoke(user,null);}long endTime = System.currentTimeMillis();System.out.println("反射的方式,不关闭检测:"+(endTime - startTime)+"ms");}public static void test03 () throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User user = new User();Class c1=user.getClass();Method getName = c1.getDeclaredMethod("getName",null);getName.setAccessible(true);long startTime = System.currentTimeMillis();for (int i = 0; i < 100000000; i++) {getName.invoke(user,null);}long endTime = System.currentTimeMillis();System.out.println("反射的方式,关闭检测:"+(endTime - startTime)+"ms");}public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {test01();test02();test03();}
}class User{String name;int age;int id;public User(String name, int age, int id) {};public User() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +", id=" + id +'}';}
}

5.反射的应用

5.1操作泛型

打印结果获取这个泛型的参数类型的相关的信息:

image-20241110150507451

5.2操作注解

下面的这个实际上是基于一个数据库的;

我们可以获取这个方法的注解,以及这个相关的属性的注解

import java.lang.annotation.*;
import java.lang.reflect.Field;public class Test{public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("demo18.Test2");Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}Tablekuang tablekuang = (Tablekuang)c1.getAnnotation(Tablekuang.class);String value = tablekuang.value();System.out.println(value);Field f = c1.getDeclaredField("name");Fieldkuang annotation = f.getAnnotation(Fieldkuang.class);System.out.println(annotation.columnName());System.out.println(annotation.type());System.out.println(annotation.length());}}
@Tablekuang("db_student")
class Test2 {@Fieldkuang(columnName = "student1",type="int",length=10)private int id;@Fieldkuang(columnName = "student2",type="int",length=10)private int age;@Fieldkuang(columnName = "student3",type="varchar",length=10)private String name;public Test2(){}public Test2(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Test{" +"id=" + id +", age=" + age +", name='" + name + '\'' +'}';}
}@Target(ElementType.TYPE)
//生命周期
@Retention(RetentionPolicy.RUNTIME)
@interface Tablekuang{//下面的这个就是我们的注解,而不是方法String value();
}//下面的这个是对于属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldkuang{//下面的这个就是我们的注解,而不是方法String columnName();String type();int length();}

下面的这个就是获取我们的属性的注解,这个里面的name是可以进行修改的,如果是name我们获得的就是这个name的注解,如果是其他的成员变量,因为这个除了name还有我们的id和age,其他的两个属性也是可以获得对应的这个注解的,我们可以获取任何的字段的这个注解;

image-20241110152251434

6.注解annotation

@override就是对于方法的重写,这个就是注解,我们经常使用,只是我们没有注意罢了;

下面的这个抑制警告的这个就是内置注解;override也是一个内置的注解;

image-20241109163259921

6.1内置注解

image-20241110095050457

6.2元注解

image-20241110095542255

我们上面的这个注解就是模仿的这个下面的源代码进行书写的,就是定义这个interface,上面的这个target里面的这个参数表示的就是作用的范围;我们上面的这个例子里面的这个是method表示这个注解只能是作用在我们的这个方法的上面,因此上面我们把这个加在test类的外面的时候,这个注解就会报错;

image-20241110095619217

当我们使用下面的这个类似于集合的方式进行表示的时候,这个的意思就是我们的这个注解不仅可以放在这个类上面,也是可以放到这个方法上面的;这个时候我们把这个注解放到这个test的外面,就不会报错了;

image-20241110095825321

我们下面的这个retention表示这个注解生效的时间,也就是这个注解的生命周期,我们可以看到这个参数里面是有三个可选项的:我们一般写作这个runntime让这个注解的生命周期长一些;

image-20241110100341347

下面的这个就是一个比较完整的演示:这个里面的@interface表示的是一个自定义的注解,我们后面还会遇到,其他的就是我们的元注解;

image-20241110100452427

6.3自定义注解

image-20241110101801187
们的这个注解不仅可以放在这个类上面,也是可以放到这个方法上面的;这个时候我们把这个注解放到这个test的外面,就不会报错了;

image-20241110095825321

我们下面的这个retention表示这个注解生效的时间,也就是这个注解的生命周期,我们可以看到这个参数里面是有三个可选项的:我们一般写作这个runntime让这个注解的生命周期长一些;

image-20241110100341347

下面的这个就是一个比较完整的演示:这个里面的@interface表示的是一个自定义的注解,我们后面还会遇到,其他的就是我们的元注解;

image-20241110100452427

6.3自定义注解

image-20241110101801187

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

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

相关文章

【React】深入理解 JSX语法

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解 JSX语法1. JSX 简介2. JSX 的基本语法2.1 基本结构2.2 与普通 JavaScr…

Spark中给读取到的数据 的列 重命名的几种方式!

目录 一、第一种 (withColumnRenamed) 二、第二种&#xff08;toDF&#xff09; 三、第三种&#xff08; toDF(*tuple1) &#xff09; 四、 第四种(schema) 五、假如文件里自带有列名的情况&#xff08;option&#xff09; 一、第一种 (withColumnRenamed) 假设要把如下…

M1M2 MAC安装windows11 虚拟机的全过程

M1/M2 MAC安装windows11 虚拟机的全过程 这两天折腾了一下windows11 arm架构的虚拟机&#xff0c;将途中遇到的坑总结一下。 1、虚拟机软件&#xff1a;vmware fusion 13.6 或者 parallel 19 &#xff1f; 结论是&#xff1a;用parellel 19。 这两个软件都安装过&#xff0…

IEEE JSSC更新|Tiny Tapeout:让每个人都能设计定制芯片

简介 由于成本高昂且需要专业技术&#xff0c;设计和制造定制集成电路的传统上仅限于大型公司和机构。然而&#xff0c;名为Tiny Tapeout的创新项目正在改变这一现状&#xff0c;让业余爱好者、学生和小型团队也能设计定制芯片。本文将探讨Tiny Tapeout的工作原理&#xff0c;以…

Java:一段代码,无限可能

Java&#xff0c;诞生于1995年&#xff0c;如今已走过近三十载春秋。它历经互联网泡沫的兴衰、移动互联网的浪潮&#xff0c;以及云计算和大数据的洗礼&#xff0c;依然屹立在编程语言的舞台中央&#xff0c;散发着耀眼的光芒。这篇文章将带你回顾Java的辉煌历史&#xff0c;探…

《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析

本文是将文章《XGBoost算法的原理推导》中的公式单独拿出来做一个详细的解析&#xff0c;便于初学者更好的理解。 我们定义一颗树的复杂度 Ω Ω Ω&#xff0c;它由两部分组成&#xff1a; 叶子结点的数量&#xff1b;叶子结点权重向量的 L 2 L2 L2范数&#xff1b; 公式(…

Linux【基础篇】

-- 原生罪 linux的入门安装学习 什么是操作系统&#xff1f; 用户通过操作系统和计算机硬件联系使用。桥梁~ 什么是Linux&#xff1f; 他是一套开放源代码&#xff08;在互联网上找到Linux系统的源代码&#xff0c;C语言写出的软件&#xff09;&#xff0c;可以自由 传播&…

大数据技术在智慧医疗中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 大数据技术在智慧医疗中的应用 大数据技术在智慧医疗中的应用 大数据技术在智慧医疗中的应用 引言 大数据技术概述 定义与原理 发…

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 三种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过 rpm 包安装&#xff0c;需具备基础概念及常规操作。 三、通过 gz 包安装&#xff0c;需具备配置相关操作。 --------…

CSS如何改变滚动条的颜色样式粗细?

默认滚动条很丑怎么办&#xff1f;如何改版滚动条的粗细&#xff0c;颜色&#xff0c;让它更美观&#xff1f;CSS如何改变滚动条的粗细&#xff1f; 干货来了 /* Webkit内核浏览器的滚动条样式 */ ::-webkit-scrollbar {width: 4px; /* 设置滚动条的宽度 */ }::-webkit-scroll…

YOLOv11(Ultralytics)可视化界面ui设计,基于pyqt5,单文件即插即用,支持文件夹检测及云摄像头检测并保存

本文的可视化界面对于YOLOv11/Ultralytics/YOLOv8的检测、分割、分类、姿势估算&#xff08;detection, segmentation, obb, classification, and pose estimation&#xff09;等均可正常显示。本次新增了图片及视频的保存&#xff0c;可以选择传入文件夹进行检测并显示&#x…

用python开发坦克大战重制版

Python 开发坦克大战重制版&#xff1a;全面教程 引言 坦克大战是一款经典的街机游戏&#xff0c;自1985年首次推出以来&#xff0c;便吸引了无数玩家。随着时间的推移&#xff0c;许多游戏开发者开始尝试重制这款经典游戏。本文将指导你如何使用 Python 和 Pygame 库开发一个…

链式结构二叉树

数据结构 结点申请 树&#x1f332;行结构 前中后序遍历 二叉树结点个数 二叉树叶子节点个数 第k层结点个数 二叉树深度 二叉树查找值为x的结点 二叉树销毁

【2024软考架构案例题】你知道什么是 RESTful 风格吗?

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

#渗透测试#SRC漏洞挖掘#深入挖掘CSRF漏洞02

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

自动驾驶革命:从特斯拉到百度,谁将主宰未来交通?

内容概要 自动驾驶技术正在经历一个前所未有的革命性变化&#xff0c;各大企业纷纷抢占这一充满潜力的新市场。以特斯拉和百度为代表的行业巨头&#xff0c;正利用各自的优势在这一技术的赛道上展开激烈竞争。特斯拉凭借其在电动汽车和自动驾驶领域的前瞻性设计与不断革新的技…

反向代理开发

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

简记Vue3(五)—— Pinia

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

C++11语法介绍(1) -- 列表初始化{},左值和右值,右值引用和移动语义,引用折叠,完美转发

目录 1.C11的发展时间线 2.列表初始化 2.1C98传统的{} 2.2C11中的{} 2.3C11中的std::initializer_list 2.3.1vector中initializer list构造的模拟实现 2.3.2以vector为例演示initializer_list版本的构造 3.右值引用和移动语义 3.1左值和右值 3.2左值引用和右值引用 3.3…

C++编程:利用环形缓冲区优化 TCP 发送流程,避免 Short Write 问题

文章目录 1. 什么是 Short Write 问题&#xff1f;2. 如何解决 Short Write 问题&#xff1f;2.1 方法 1&#xff1a;将 Socket 设置为阻塞模式2.2 方法 2&#xff1a;用户态维护发送缓冲区 3. 用户态维护发送缓冲区实现3.1 核心要点3.2 代码实现3.3 测试程序 参考文档 1. 什么…