Day44 Java的反射案例

Day44 Java的反射案例

文章目录

  • Day44 Java的反射案例
    • 一、反射案例 之 万能数组扩容
    • 二、反射案例 之 业务与逻辑分离 的思想
    • 三、反射案例 之 操作注解

一、反射案例 之 万能数组扩容

1、基本步骤:

  1. 获取原始数组的类型
    • 使用array.getClass().getComponentType()方法获取原始数组的元素类型。
  2. 创建新数组
    • 使用Array.newInstance(type, newSize)方法根据原始数组的元素类型和新的大小创建一个新数组。
  3. 复制原始数组元素到新数组
    • 使用System.arraycopy()方法将原始数组的元素复制到新数组中。
  4. 返回新数组
    • 将新数组返回给调用者,完成数组扩容的操作。

2、示例代码:

public class Test01 {
	/**
	 * 知识点:反射案例 之 万能数组扩容
	 */
	public static void main(String[] args) {
		
		String[] ss = {"麻生希","椎名空","水菜丽","朝桐光","爱田奈奈"};
		String[] newSS = MyArrays.copyOf(ss, 8);
		System.out.println(MyArrays.toString(newSS));
		
		int[] is = {1,2,3,4,5};
		int[] newIS = MyArrays.copyOf(is, 8);
		System.out.println(MyArrays.toString(newIS));
	}
}
import java.lang.reflect.Array;

/**
 * 数组工具类
 * @author 小杨
 * @version 1.0
 */
public class MyArrays {

	/**
	 * 数组的排序
	 * @param a 目标数组
	 */
	public static void sort(int[] a){
		for (int i = 0; i < a.length-1; i++) {
			for (int j = 0; j < a.length-1-i; j++) {
				if(a[j] > a[j+1]){
					int temp = a[j];
					a[j] = a[j+1];
					a[j+1] = temp;
				}
			}
		}
	}
	
	/**
	 * 数组的查找,必须先排序,在查找
	 * @param a 目标数组
	 * @param key 需要查找的键
	 * @return 如果搜索的元素包含在数组中就返回元素的下标; 否则,返回(-插入点-1)
	 */
	public static int binarySearch(int[] a,int key){
		int start = 0;
		int end = a.length-1;
		while(start <= end){
			int mid = (start+end)/2;
			if(key < a[mid]){
				end = mid-1;
			}else if(key > a[mid]){
				start = mid+1;
			}else{
				return mid;
			}
		}
		return -start-1;
	}
	
	/**
	 * 拷贝数组
	 * @param original 目标数组
	 * @param newLength 新数组的长度
	 * @return 新数组
	 */
	public static int[] copyOf(int[] original, int newLength){
		
		int copyLength = original.length;
		if(copyLength > newLength){
			copyLength = newLength;
		}
		
		int[] newArr = new int[newLength];
		
		for (int i = 0; i < copyLength; i++) {
			newArr[i] = original[i];
		}
		return newArr;
	}
	
	/**
	 * 引用数据类型数组的扩容(不支持基本数据类型)
	 * @param original
	 * @param newLength
	 * @return
	 */
	public static <T> T[] copyOf(T[] original , int newLength){
		
		int copyLength = original.length;
		if(copyLength > newLength){
			copyLength = newLength;
		}
		
		//获取元素的类型
		Class<? extends Object[]> clazz = original.getClass();//String[].class
		Class<?> componentType = clazz.getComponentType();//String.clss
		
		//利用反射创建数组
		@SuppressWarnings("unchecked")
		T[] ts = (T[]) Array.newInstance(componentType, newLength);
		
		//遍历源数组,将数据复制到新数组中
		for (int i = 0; i < copyLength; i++) {
			//获取源数组的数据
			Object element = Array.get(original, i);
			//赋值给新数组
			Array.set(ts, i, element);
		}
		return ts;
	}
	
	/**
	 * 拷贝区间数组
	 * @param original 目标数组
	 * @param from 开始下标-包含
	 * @param to 结束下标 - 排他
	 * @return 新数组
	 */
	public static int[] copyOfRange(int[] original, int from, int to){
		
		int newLength = to-from;
		int[] newArr = new int[newLength];
		
		int index = 0;
		for (int i = from; i < to; i++) {
			newArr[index++] = original[i];
		}
		return newArr;
	}
	
	/**
	 * 替换全部元素
	 * @param a 目标数组
	 * @param val 替换的值
	 */
	public static void fill(int[] a, int val){
		fill(a, 0, a.length, val);
	}
	
	/**
	 * 替换区间元素
	 * @param a 目标数组
	 * @param fromIndex 开始下标 - 包含
	 * @param toIndex 结束下标 - 排他
	 * @param val 替换的值
	 */
	public static void fill(int[] a, int fromIndex, int toIndex, int val){
		for (int i = fromIndex; i < toIndex; i++) {
			a[i] = val;
		}
	}
	
	/**
	 * 将数组转换为字符串
	 * @param a 目标数组
	 * @return 转换后的字符串
	 */
	public static String toString(int[] is) { 
		StringBuffer sb = new StringBuffer();
		
		sb.append("[");
		
		for (int element : is) {
			if(sb.length() != 1){
				sb.append(",");
			}
			sb.append(element);
		}
		sb.append("]");
		return sb.toString();
	}
	
	/**
	 * 将数组转换为字符串
	 * @param a 目标数组
	 * @return 转换后的字符串
	 */
	public static <T> String toString(T[] a){
		
		StringBuffer sb = new StringBuffer();
		
		sb.append("[");
		
		for (int i = 0; i < Array.getLength(a); i++) {
			if(sb.length() != 1){
				sb.append(",");
			}
			Object element = Array.get(a, i);
			sb.append(element);
		}
		
		sb.append("]");
		return sb.toString();
	}
	
}

二、反射案例 之 业务与逻辑分离 的思想

1、基本步骤:

  1. 定义接口
    • 首先,定义一个接口来描述业务逻辑的操作,接口中包含需要实现的方法。
  2. 编写具体实现类
    • 编写实现接口的具体业务逻辑类,每个类负责实现接口中定义的方法,完成具体的业务逻辑。
  3. 利用反射动态加载类
    • 在一个通用的类中,通过反射机制动态加载指定的类,实现业务逻辑与具体实现类的解耦。
  4. 创建实例并调用方法
    • 利用反射创建实例,并调用接口中定义的方法执行业务逻辑。

2、示例代码:

import java.util.ArrayList;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;



public class Test01 {
	/**
	 * 知识点:反射案例 之  业务与逻辑分离 的思想
	 * 
	 * 需求:用户选择获取数据的方式(本地数据、网络数据)
	 */
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		showMenu();
		int num = scan.nextInt();
		
		DataSource dataSource = getDataSourceObject(num);
		dataSource.getDataSource();
		
		scan.close();
	}
	
	public static void showMenu(){
		System.out.println("请选择获取数据的方式:");
		ArrayList<String> menulist = DataCenter.menuList;
		for (String element : menulist) {
			System.out.println(element);
		}
	}
	
	public static DataSource getDataSourceObject(int num){
		DataSource dataSource = DataCenter.dataSourceList.get(num-1);
		return dataSource;
	}
}

//数据中心
public class DataCenter {

	public static final ArrayList<String> menuList;
	public static final ArrayList<DataSource> dataSourceList;
	
	//初始化菜单数据
	static{
		
		menuList = new ArrayList<>();
		
		Properties p = new Properties();
		try {
			p.load(DataCenter.class.getClassLoader().getResourceAsStream("menuConfig.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		String data = p.getProperty("data");
		String[] split = data.split(",");
		Collections.addAll(menuList, split);
	}
	
	//初始化数据源数据
	static{
		
		dataSourceList = new ArrayList<>();
		
		Properties p = new Properties();
		try {
			p.load(DataCenter.class.getClassLoader().getResourceAsStream("dataSourceConfig.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		String data = p.getProperty("data");
		String[] split = data.split(",");
		for (String classPath : split) {
			try {
				Class<?> clazz = Class.forName(classPath);
				DataSource dataSouce = (DataSource) clazz.newInstance();
				dataSourceList.add(dataSouce);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}		
		}
	}
}
public abstract class DataSource {

	public abstract void getDataSource();
	
}

//获取本地资源的类
public class LocalDataSource extends DataSource{

	private Scanner scan;
	
	public LocalDataSource() {
		scan = new Scanner(System.in);
	}
	
	@Override
	public void getDataSource() {
		
		System.out.println("请填写需要拷贝文件的路径:");
		String path = scan.next();
		File file = new File(path);
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(new FileInputStream(path));
			bos = new BufferedOutputStream(new FileOutputStream(file.getName()));
			
			byte[] bs = new byte[1024];
			int len;
			while((len=bis.read(bs)) != -1){
				bos.write(bs, 0, len);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(bis != null){
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bos != null){
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

//获取网络资源的类
public class NetworkDataSource extends DataSource{

	private Scanner scan;
	
	public NetworkDataSource() {
		scan = new Scanner(System.in);
	}

	@Override
	public void getDataSource() {
		//https://wx2.sinaimg.cn/mw690/e2438f6cly1hoo3qpm7vrj21111jk4mn.jpg
		System.out.println("请填写下载图片的网址:");
		String path = scan.next();
		
		try {
			//创建链接对象
			URL url = new URL(path);
			//获取连接对象
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			
			//设置参数
			connection.setConnectTimeout(5000);//设置连接超时时间
			connection.setReadTimeout(5000);//设置读取数据超时时间
			connection.setDoInput(true);//设置是否允许使用输入流
			connection.setDoOutput(true);//设置是否允许使用输出流
			
			//获取响应状态码
			int code = connection.getResponseCode();
			if(code == HttpURLConnection.HTTP_OK){
				
				//文件名
				String fileName = path.substring(path.lastIndexOf("/")+1);
				
				BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileName));
				byte[] bs = new byte[1024];
				int len;
				while((len = bis.read(bs)) != -1){
					bos.write(bs, 0, len);
				}
				
				bis.close();
				bos.close();
				
			}else if(code == HttpURLConnection.HTTP_NOT_FOUND){
				System.out.println("页面未找到");
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
public class OtherDataSource extends DataSource{

	@Override
	public void getDataSource() {
		System.out.println("获取其他数据");
	}

}

三、反射案例 之 操作注解

1、基本步骤:

  1. 定义注解
    • 首先,定义一个注解,可以通过元注解@Target@Retention指定注解的作用目标和生命周期,定义注解的属性。
  2. 在类、方法、字段上使用注解
    • 在需要使用注解的类、方法、字段上使用定义好的注解,可以为注解的属性赋值。
  3. 利用反射获取注解信息
    • 使用反射机制获取类、方法、字段上的注解信息,可以通过getAnnotation()方法获取指定的注解实例,进而获取注解的属性值。
  4. 根据注解信息进行处理
    • 根据获取到的注解信息,可以编写相应的逻辑来处理注解,例如根据注解的属性值执行不同的操作。
  5. 动态生成带有注解的类、方法、字段
    • 可以通过反射机制动态生成带有注解的类、方法、字段,并在运行时进行相应的处理。

注意: 通过这些步骤,可以实现对注解的操作,包括获取注解信息、根据注解信息进行相应的处理,实现了业务逻辑与注解的解耦,提高了代码的灵活性和可扩展性。

2、示例代码:

import java.lang.reflect.Field;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test01 {
	/**
	 * 知识点:反射案例 之 操作注解
	 */
	public static void main(String[] args) {
		
		Student stu = new Student("马智威", "男", 18);
		
		String sql = DBUtil.generateInsertSQL(stu);
		System.out.println(sql);
		//INSERT INTO s_student(s_name,s_sex,s_age) VALUES('小杨','男',18);
	}
}

public class DBUtil {

	public static String generateInsertSQL(Object obj){
		
		Class<? extends Object> clazz = obj.getClass();
		
		//获取表名
		TableInfo tableInfo = clazz.getAnnotation(TableInfo.class);
		if(tableInfo == null){
			throw new RuntimeException();
		}
		String tableName = tableInfo.name();
		
		StringBuffer names = new StringBuffer();
		StringBuffer values = new StringBuffer();
		
		//获取属性数据
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			
			FieldInfo fieldInfo = field.getAnnotation(FieldInfo.class);
			String name = fieldInfo.name();
			String type = fieldInfo.type();
			
			if(names.length() != 0){
				names.append(",");
			}
			names.append(name);
			
			try {
				
				if(values.length() != 0){
					values.append(",");
				}
				
				Object fieldData = field.get(obj);
				if(type.equals("varchar")){
					values.append("'");
				}
				values.append(fieldData);
				if(type.equals("varchar")){
					values.append("'");
				}
				
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		
		String sql = "INSERT INTO " + tableName + "(" + names.toString() + ") VALUES(" + values.toString() + ");";
		return sql;
	}
	
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInfo {
	String name();
	String type();
}
@TableInfo(name="s_student")
public class Student {

	@FieldInfo(name="s_name",type="varchar")
	private String name;
	
	@FieldInfo(name="s_sex",type="varchar")
	private String sex;
	
	@FieldInfo(name="s_age",type="int")
	private int age;
	
	public Student() {
	}

	public Student(String name, String sex, int age) {
		this.name = name;
		this.sex = sex;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableInfo {
	
	String name();
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20.4中复现Graspness

Ubuntu20.4中复现Graspness 文章目录 Ubuntu20.4中复现Graspness1.安装cuda和cudnn2.安装pytorch3.安装MinkowskiEngine4.编译graspnetAPI5. RuntimeError: "floor" "_vml_cpu" not implemented for IntRefernece &#x1f680;非常重要的环境配置&#x1…

pyqt 分组框控件QGroupBox

pyqt 分组框控件QGroupBox 分组框控件QGroupBox介绍效果代码 分组框控件QGroupBox介绍 QGroupBox提供了一个框架&#xff0c;用于将其他控件&#xff08;如按钮、滑块、标签等&#xff09;组合在一起。 QGroupBox 通常包含一个标题栏和一个内容区域。标题栏显示文本标签&#…

经典回溯算法之N皇后问题

问题描述&#xff1a; 有一个N*N的棋盘&#xff0c;需要将N个皇后放在棋盘上&#xff0c;保证棋盘的每一行每一列每一左斜列每一右斜列都最多只能有一个皇后。 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如…

关于模型参数融合的思考

模型参数融合通常指的是在训练过程中或训练完成后将不同模型的参数以某种方式结合起来&#xff0c;以期望得到更好的性能。这种融合可以在不同的层面上进行&#xff0c;例如在神经网络的不同层之间&#xff0c;或者是在完全不同的模型之间。模型参数融合的目的是结合不同模型的…

探索智慧生活:百度Comate引领人工智能助手新潮流

文章目录 百度Comate介绍1. 什么是百度Comate&#xff1f;主要特点 2. Comate的核心功能智能问答功能语音识别功能语音助手功能个性化服务 使用教程(以vscode为例)1. 下载和安装Comate2. 插件配置方式1&#xff1a;无License用户方式2&#xff1a;购买License用户 3. 常用操作快…

软件设计师

软件设计师 第一章 计算机系统基础原/反/补/移码例题&#xff1a; 浮点数例题 海明校验码例题 CISC和RISC*流水线例题 存储系统cache*主存编址计算例题&#xff1a; 可靠性例题 性能指标例题 第二章 操作系统进程例题 PV操作 信号量例题 前驱图例题 死锁计算例题 段页式存储例题…

阵痛中的乳业产业,何时才能成为下一个啤酒产业?

说起饮品&#xff0c;近年来中国啤酒业中各大品牌齐齐聚焦高端化的趋势绝对值得一提。然而&#xff0c;与之相反&#xff0c;国内乳业却是仍未进入高端化阶段&#xff0c;甚至陷入了周期底部中。 图源&#xff1a;中国圣牧财报 增收降利 牧企承受巨大的供需缺口压力 从产业链…

设计模式(2)创造型设计模式

创建型模式 创建型模式1.工厂模式1.1 抽象工厂模式&#xff08;Abstract factory&#xff09;1.2 工厂方法模式&#xff08;Factory Method&#xff09;1.3 简单工厂模式&#xff08;Simple Factory&#xff09; 2. 建造者模式&#xff08;Builder&#xff09;3. 原型模式&…

P8799 [蓝桥杯 2022 国 B] 齿轮

P8799 [蓝桥杯 2022 国 B] 齿轮 分析 最右边的齿轮的转速是最左边齿轮的q倍 最右边的齿轮的半径是最左边齿轮的q倍 题意即为&#xff1a;查询数组中是否存在两个数&#xff0c;其中一个是另一个的q倍 题目范围&#xff1a;查询次数q:2*10^5&#xff0c;数组范围2*10^5&…

2024付费进群系统,源码及搭建变现视频课程(教程+源码)

前三节讲解搭建支付对接&#xff0c;后两节讲解一些引流变现的方法&#xff0c;还有一种变现就是帮人搭建这样的平台&#xff0c;因为全网都没有一套完整的视频教怎么搭建的&#xff0c;有也只是文字教程&#xff0c;一般新人根本看不懂&#xff0c;我视频实操演示&#xff0c;…

学习经验分享【36】论文投稿写作(非理工科文章)

业务进一步扩展&#xff0c;可辅导非理工科偏文科性质的论文辅导&#xff0c;有需要评职称但没有时间精力研究的或者其他相关需求的朋友可咨询了解。 人工智能技术在各领域的发展和思考&#xff0c;类似这种主题的文章。

压缩和归档库-LZ4介绍

1.简介 LZ4是一种快速的压缩算法&#xff0c;提供压缩和解压缩的速度&#xff0c;而牺牲了压缩率。它被设计用于快速的数据压缩和解压缩&#xff0c;特别是用于数据存储和传输。LZ4通常用于需要高速数据处理的场景&#xff0c;如数据库、日志文件处理和实时数据传输。 LZ4的特…

进一步分析并彻底解决 Flink container exit 143 问题

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

腾讯游戏海外扩张,增持芬兰游戏开发商股份持股比例增至14.8%

易采游戏网5月8日消息&#xff0c;近日腾讯再次出手&#xff0c;大幅增持了芬兰知名游戏开发商Remedy Entertainment的股份&#xff0c;持股比例猛增至14.8%。这一举动引起了业界和投资者的广泛关注。 据了解&#xff0c;腾讯此次增持是在2024年4月24日完成的。根据芬兰法律规…

Linux网络-PXE高效批量网络装机(命令+截图详细版)

目录 一.部署PXE远程安装服务 1.PXE概述 1.1.PXE批量部署的优点 1.2.要搭建PXE网络体系的前提条件 2.搭建PXE远程安装服务器 2.1.修改相关网络配置&#xff08;仅主机模式&#xff09; 2.2.关闭防火墙&#xff08;老规矩&#xff09; 2.3.保证挂载上 2.4.准备好配置文…

<网络安全>《76 概念讲解<第十课 物联网常用协议-网络层协议>》

协议简称全称名称内容说明IPv4互联网通信协议第四版IPv4是互联网的核心IPv6互联网协议第6版TCPTransmission Control Protocol传输控制协议TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务…

【Python】什么是皮尔森系数

我不完美的梦 你陪着我想 不完美的勇气 你说更勇敢 不完美的泪 你笑着擦干 不完美的歌 你都会唱 我不完美心事 你全放在心上 这不完美的我 你总当做宝贝 你给我的爱也许不完美 但却最美 &#x1f3b5; 周冬雨《不完美女孩》 皮尔森相关系数&#xff08;Pe…

FinalShell连接虚拟机Linux系统连接超时

报错信息 java.net.ConnectException: Connection timed out: connect 排除是网络问题后可以尝试一下这个方法。 解决方案: 打开虚拟机终端输入:ifconfig 会出现端口信息: 看ens33这里的端口是多少&#xff0c;改一下重新连接就ok。

springboot+vue实现登录注册,短信注册以及微信扫描登录

说明&#xff1a;微信扫描登录需要微信注册--要钱&#xff0c;感谢尚硅谷提供的免费接口&#xff1b;短信注册需要阿里云的注册很麻烦并且短信费&#xff0c;没有接口&#xff0c;所以不打算实现&#xff0c;不过能做出效果。 目录 一、建立数据库 二、后端idea实现接口 1.…

幻兽帕鲁专用服务器怎样买省钱便宜?一个月30元

在数字娱乐的浪潮中&#xff0c;幻兽帕鲁Palworld以其独特的魅力吸引了无数玩家的目光。想要拥有流畅、稳定的游戏体验&#xff0c;一台专属的游戏服务器是必不可少的。而如何以最经济的价格购买到高品质的服务器&#xff0c;正是玩家们最关心的问题。腾讯云服务器性价比是很高…
最新文章