Java使用反射的通用数组复制方法
Java通用数组复制方法
在Arrays工具类中,提供了一个copyOf(T[] original, int newLength)
方法,用于复制任意类型的对象数组,但是由于泛型不能作用于基本类型,所以Arrays工具类中又额外提供了处理基本数据类型数组的函数,但是使用反射可以讲这些方法都统一起来。
为了对比,先来看一个实现的不太好的数组拷贝的例子:
public static Object[] badCopy(Object[] objects, int newLength) {
Object[] des = new Object[newLength];
System.arraycopy(objects, 0, des, 0, Math.min(newLength, objects.length));
return des;
}
这个方法copy方法在很多情况下也能正常工作,但是存在很多问题。
首先,只能拷贝对象数组。因为传递的参数是Object[]
,所以难以扩展到基本类型;
其次,由于使用Object[]
声明新数组,所以没法将返回结果转换为想要拷贝的实际类型。比如想拷贝的是Person对象的数组,但是这里的返回值是一个Object的数组,而且还无法转换成。在Java中,如果一开始声明的是Object对象,将它临时转换到Object,然后再转回来是可以的,但是如果一开始就声明了Object,就无法向下转型了,Java会记住声明时的类型信息,也就是一个对象的静态类型信息。
为了解决以上问题,使用如下的方法:
public static Object copyOf(Object arr, int newLength) {
Class cl = arr.getClass();
// 如果不是数组 返回
if (!cl.isArray()) return null;
// 获取数组中元素的类型
Class componentType = cl.getComponentType();
// 创建新数组实例
Object res = Array.newInstance(componentType, newLength);
System.arraycopy(arr, 0, res, 0, Math.min(newLength, Array.getLength(arr)));
return res;
}
该方法接受Object对象作为参数,所以可以处理基本类型,因为数组总是一个对象,对象类型的数组是一个数组对象,基本类型的数组同样是数组对象,所以可以正确的传递参数;
再看内部实现中,获取数组的类对象,然后再使用获取数组中元素的类型,用这个类型来创建新的数组,这就保证了最终可以将结果向下转型为想要的类型;返回的类型是Object,通过上述描述可知,得到结果后,只要手动的转换成想要的类型即可。
public static void main(String[] args) {
int[] a = new int[]{1, 2, 3, 4};
int[] b = (int[]) CopyArray.copyOf(a, 3);
System.out.println(Arrays.toString(b));
String[] c = new String[]{"xx", "yy", "zz"};
String[] d = (String[]) CopyArray.copyOf(c, 10);
System.out.println(Arrays.toString(d));
}
这个方法虽然可以将所有类型数组的拷贝统一,但是不好的地方在于需要手动进行类型转换,而Arrays工具类中,虽然没有统一所有方法,但是使用重载将让用户可以更方便的使用,而不需要类型转换。
或许这就是通用和专用的权衡吧。
Java使用反射的通用数组复制方法的更多相关文章
- Java -- 利用反射 操作任意数组,包括对象数组 和 基本数据类型的数组
items为任意数组
- java开发--反射技术
学习目标: 1.什么是反射:即反射的定义, 2.反射有什么作用,能解决什么问题, 3.反射的知识点是什么, 4.反射的利弊 5.反射的例子 1.什么是反射:反射的定义: a) 能够分析类能力的程序被称 ...
- 面试题思考:什么是 Java 的反射机制
一.反射机制概述 Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法.这种在运行时动态的获取信息以及动态调用对象的方法 ...
- 利用反射实现通用的excel导入导出
如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 package com.bean; p ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- Java:反射
初识Java反射机制: 从上面的描述可以看出Java的反射机制使得Java语言可以在运行时去认识在编译时并不了解的类/对象的信息,并且能够调用相应的方法或修改属性的值.Java反射机制的核心就是允许在 ...
- Java数据结构和算法之数组与简单排序
一.数组于简单排序 数组 数组(array)是相同类型变量的集合,可以使用共同的名字引用它.数组可被定义为任何类型,可以是一维或多维.数组中的一个特别要素是通过下标来访问它.数组提供了一种将有联系的信 ...
- java笔记--反射进阶之总结与详解
一.反射进阶之动态设置类的私有域 "封装"是Java的三大特性之一,为了能更好保证其封装性,我们往往需要将域设置成私有的, 然后通过提供相对应的set和get方法来操作这个域.但是 ...
随机推荐
- Game of Sum
可以知道整体石子的总和一定的,所以一个人的得分越高,另一个人的得分就越低.不管怎么取任意时刻游戏的状态都是原始序列的一段连续子序列(即被玩家取剩下的序列). 因此,用d(i,j)表示玩家A在i到j部分 ...
- post请求下载文件,获取Content-Disposition文件名
1.post下载文件代码,doload方法 import request from "../../src/utils/request"; import { API } from & ...
- 数据库的查询(结合YGGL.sql)
(如有错误,欢迎指正!) 1.select 语句查询 (1)查询employees表员工部门号和性别,要求消除重复行. mysql> select distinct 员工部门号,性别 from ...
- 如何使用Pycharm在网页上展示诗歌。(HTML)
!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g ...
- springboot项目打war包流程
目前,前后端分离的架构已成主流,因此使用springboot构建应用是非常快速的,项目发布到服务器上的时候,只需要打成一个jar包,然后通过命令 : java -jar jar包名称即可启动服务了:但 ...
- PHP 导入Excel数据 到数据库
/** * 导入excel * @throws \PHPExcel_Exception * @throws \PHPExcel_Reader_Exception */ public function ...
- 【Nginx】yum安装nginx
这里是nginx的yum安装源: centos7: rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-cent ...
- Unsafe Fileupload - Pikachu
概述: 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像.上传附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型.后缀名.大小等等,然后将其按照设计 ...
- kafka(三)原理剖析
一.生产者消息分区机制原理剖析 在使用Kafka 生产和消费消息的时候,肯定是希望能够将数据均匀地分配到所有服务器上.比如很多公司使用 Kafka 收集应用服务器的日志数据,这种数据都是很多的,特别是 ...
- layui表格前端格式化时间戳字段
layui.use(['util','table'], function(){ var table = layui.table; var util = layui.util; //... ...