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方法来操作这个域.但是 ...
随机推荐
- Head First 设计模式 - 01. 策略 (Strategy) 模式
当涉及到"维护"时,为了"复用"目的而使用继承,结局并不完美 P4 对父类代码进行修改时,影响层面可能会很大 思考题 利用继承来提供 Duck 的行为,这会导致 ...
- MAC与ARP缓存中毒介绍
ARP 协议 用于地址解析,请求MAC地址. arp -a 或者 -n 查看ARP缓存表 ls(ARP) 查看scapy里的协议字段 ARP缓存中毒原理 ARP收到ARP请求报文,会将发送方的mac地 ...
- nodejs事件和事件循环详解
目录 简介 nodejs中的事件循环 phase详解 timers pending callbacks idle, prepare poll轮询 check close callbacks setTi ...
- Sentry(v20.12.1) K8S 云原生架构探索,SENTRY FOR JAVASCRIPT Source Maps 详解
系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...
- Java通过基姆拉尔森公式判断当前日期是不是工作日
基姆拉尔森公式 算法如下: 基姆拉尔森计算公式 W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7 在公式中d表示日期中的日数,m表示月份数,y表示年数. 注意:在公 ...
- 剑指offer之重建二叉树
1.问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列pre {1,2,4,7,3,5,6, ...
- dubbo配置启动时检查
启动检查设置 Dubbo缺省会在启动时检查依赖的服务是否可用,不可用会抛出异常,阻止Spring初始化完成,默认check="true":是开启检查. 比如测试的时候,有些服务并不 ...
- 【Problem】前端项目运行:Module build failed:Error Node Sass does not yet support my current environmen
我在运行renren-fast-vue前端项目时,安装完依赖cnpm install 启动服务npm run dev 出现问题. Module build failed: Error: Node Sa ...
- Linux Shell 编程基础详解——吐血整理,墙裂推荐!
第一部分:Linux Shell 简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序, ...
- CTFHub - Web(四)
最近又是每天忙到裂开,,,淦 xss: 反射型: 1.第一个输入框与下面Hello后的内容相同,猜测可以通过该输入,改变页面内容. 测试语句: <script>alert(1)</s ...