学习JavaEE的日子 Day40 反射案例

Day40

1.反射案例 之 万能数组扩容

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));
	}
}

MyArrays类

public class MyArrays {
	
	/**
	 * 拷贝数组(以前的方法)
	 * @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 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();
	}
	
}

2.反射案例 之 业务与逻辑分离 的思想

invoke方法参数的意义

参数一:表示代理对象,一般不用(了解)

参数二:就是方法名,我们可以对方法名进行判断,是增强还是拦截

参数三:调用方法时,传递的参数

需求:用户选择获取数据的方式(本地数据、网络数据)

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;
	}
}

配置文件

dataSourceConfig.properties

data=com.qf.reflex02.LocalDataSource,com.qf.reflex02.NetworkDataSource,com.qf.reflex02.OtherDataSource

menuConfig.properties

data=1-\u83B7\u53D6\u672C\u5730\u6570\u636E,2-\u83B7\u53D6\u7F51\u7EDC\u6570\u636E,3-\u83B7\u53D6\u5176\u4ED6\u6570\u636E
public abstract class DataSource {

	public abstract void getDataSource();
	
}

数据中心类(选择1,2,3,继续第几个操作)

//数据中心
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 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("获取其他数据");
	}

}

3.反射案例 之 操作注解

利用注解使Student类的属性与数据库表名一致,与mybatis的起别名差不多

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);
	}
}

类名注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableInfo {
	
	String name();
}

属性注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInfo {
	String name();
	String type();
}

Student类

@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;
	
	//有参构造,无参构造,get,set方法省略
}

数据库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;
	}
	
}

你觉得反射好不好?好,有两个方向

第一个方向:无视修饰符访问类中的内容。但是这种操作在开发中一般不用,都是框架底层来用的。

第二个方向:反射可以跟配置文件结合起来使用,动态的创建对象,动态的调用方法。

总结

1.反射案例 – 万能数组扩展
注意:
1.泛型的使用
2.利用Array操作数组

2.反射案例 – 业务与逻辑分离的思想
注意:
1.理解思想
2.灵活使用配置文件
3.理解数据中心DataCenter

3.反射案例 – 操作注解
注意:
1.理解注解是可以给类、属性、方法提供额外信息

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

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

相关文章

信息系统项目管理师0056:数据管理(4信息系统管理—4.2管理要点—4.2.1数据管理)

点击查看专栏目录 文章目录 4.2管理要点4.2.1数据管理1.数据战略2.数据治理3.数据架构4.数据应用5.数据安全6.数据质量7.数据标准8.数据生存周期9.理论框架与成熟度4.2管理要点 信息系统管理涉及系统准备、设计、实施、运行等活动的众多方面,

基于SpringBoot的在线五子连珠的设计与实现,前端采用vue框架;后端采用SpringBoot,mybatis

介绍 基于SpringBoot的在线五子连珠的设计与实现&#xff0c;主要是设计一款五子棋游戏&#xff0c;涉及登录注册的功能&#xff0c;人机对战、联机对战和积分排行榜的功能。其中人机对战中&#xff0c;电脑采用的是采用了一种基于局面分析的评分算法来确定机器人的下一步落子…

java 红黑树

01.红黑树的定义&#xff1a; 每一个结点有五个属性&#xff1a;

书生浦语大模型实战训练营--第二期第六节--Lagent AgentLego 智能体应用搭建--homework

一、基础作业 1.完成 Lagent Web Demo 使用&#xff0c;并在作业中上传截图 根据以下命令启动成功&#xff01; 2.完成 AgentLego 直接使用部分&#xff0c;并在作业中上传截图 这是原图 使用AgentLego进行自动目标检测后&#xff0c;很明显图中的物体已经被识别出来了 二、…

ElasticSearch可视化工具:kibana + elasticsearch-head

kibana 下载 地址&#xff1a;https://www.elastic.co/cn/downloads/kibana 下载别的版本&#xff1a;https://www.elastic.co/cn/downloads/past-releases#kibana 将Kibana安装包解压缩 进入config目录&#xff0c;在kibana.yml中添加es服务器地址。&#xff08;如果之前没…

Latex使用algoritm2e出现的错误汇总(updating)

1. return 和 end在一行 解决办法是&#xff1a;\Return{}中必须使用latex公式&#xff0c;如&#xff1a;\Return{$S_b$}

uniapp全局监听分享朋友圈或朋友

把大象装进冰箱需要几步&#xff1a; 1、创建shart.js文件 export default{data(){return {//设置默认的分享参数//如果页面不设置share&#xff0c;就触发这个默认的分享share:{title:标题,path:/pages/index/index,imageUrl:图片,desc:描述,content:内容}}},onLoad(){let ro…

Android的一些总结

先打开自定义的app显示欢迎->消失 打开桌面应用程序->在桌面应用程序中也要能一键启动打开视频播放的app 桌面应用程序广播接收者进行监听&#xff0c;然后打开服务/activity是可行的。 ########################## 日志&#xff0c;调试&#xff1a; Usb 无线 串口…

机器学习预测汽车油耗效率 MPG

流程 数据获取导入需要的包引入文件,查看内容划分训练集和测试集调用模型查看准确率 数据获取 链接&#xff1a;https://pan.baidu.com/s/1KeIJykbcVpsfEk0xjhiICA?pwd30oe 提取码&#xff1a;30oe --来自百度网盘超级会员V1的分享导入需要的包 import pandas as pd imp…

华为认证实验配置(10): 实现VLAN间通信

传统交换二层组网中&#xff0c;默认所有网络都处于同一个广播域&#xff0c;这带了诸多问题。VLAN技术的提出&#xff0c;满足了二层组网隔离广播域需求&#xff0c;使得属于不同VLAN的网络无法互访&#xff0c;但不同VLAN之间又存在着相互访问的需求 重点&#xff1a;使用路…

【人工智能】机器学习算法综述及常见算法详解

目录 推荐 1、机器学习算法简介 1.1 机器学习算法包含的两个步骤 1.2 机器学习算法的分类 2、线性回归算法 2.1 线性回归的假设是什么&#xff1f; 2.2 如何确定线性回归模型的拟合优度&#xff1f; 2.3 如何处理线性回归中的异常值&#xff1f; 3、逻辑回归算法 3.1 …

公园高速公路景区校园IP网络广播音柱SIP音柱

公园高速公路景区校园IP网络广播音柱SIP音柱 适用于学校、车站、教堂、工厂、仓库、公园停车场及露天市场高速公路等场所播放录制语音文件或背景音乐节目&#xff0c;专业一体化音箱设计&#xff0c;高强度防水设计&#xff0c;符合IP54防护等认证&#xff0c;数字化产品&…

.net6项目模板

1.集成log4net 安装依赖包&#xff1a; 安装扩展依赖即可&#xff0c;已经包含了log4net依赖&#xff1a; Microsoft.Extensions.Logging.Log4Net.AspNetCore 添加日志配置文件&#xff1a; 日志配置文件属性设置为始终复制&#xff1a; 注入服务&#xff1a; #region 注入…

Spring Boot 实现接口幂等性的 4 种方案

一、什么是幂等性 幂等是一个数学与计算机学概念&#xff0c;在数学中某一元运算为幂等时&#xff0c;其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中&#xff0c;一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂…

微信小程序开发之多图片上传+.NET WebAPI后端服务保存图片资源

前言&#xff1a; 最近开发的一个微信小程序项目需要做一个同时选中三张&#xff08;或者是多张&#xff09;图片一起上传到服务端&#xff0c;服务端保存图片资源并保存的功能。发现在微信小程序开发中会有很多场景会使用到多图片上传并保存到的功能&#xff0c;所以我把自己总…

高频前端面试题汇总之Vue篇

1. Vue的基本原理 当一个Vue实例创建时&#xff0c;Vue会遍历data中的属性&#xff0c;用 Object.defineProperty&#xff08;vue3.0使用proxy &#xff09;将它们转为 getter/setter&#xff0c;并且在内部追踪相关依赖&#xff0c;在属性被访问和修改时通知变化。 每个组件实…

Stable Diffusion 模型分享:ChilloutMix(真实、亚洲面孔)chilloutmix_NiPrunedFp32Fix

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 相信近来吸引大家想一试 Stable Diffusion 图像生…

【EI会议征稿】2024年先进机械电子、电气工程与自动化国际学术会议(ICAMEEA 2024)

2024 International Conference on Advanced Mechatronic, Electrical Engineering and Automation ●会议简介 2024年先进机械电子、电气工程与自动化国际学术会议&#xff08;ICAMEEA 2024&#xff09;将汇聚全球机械电子、电气工程与自动化领域的专家学者&#xff0c;共同…

洗眼镜什么牌子的超声波清洗机好用?全网一致好评四大品牌

眼镜作为我们日常佩戴的必备单品&#xff0c;你是否真正关注过它的清洁度&#xff1f;眼镜不清洗&#xff0c;不仅影响视力&#xff0c;还可能对眼睛造成不可逆的伤害。因此&#xff0c;眼镜一定要经常清洗&#xff0c;而超声波清洗机则是你洗眼镜的最佳选择。在市面上&#xf…

新项目应该选mongodb还是postgresql?

文章目录 MongoDBPostgreSQL大数据处理时的优势对比实际使用经验 选择MongoDB还是PostgreSQL作为新项目的数据库&#xff0c;主要取决于项目的具体需求、数据模型、应用场景以及团队熟悉程度等因素。下面将从几个关键角度对两者进行对比分析。 MongoDB 数据模型&#xff1a;Mo…
最新文章