实例讲解Java编程中数组反射的使用方法
|
什么是反射
内省示例:instanceof 运算符用于检测某个对象是否属于特定的类。
if (obj instanceof Dog) {
Dog d = (Dog) obj;
d.bark();
}
反射示例:Class.forName()方法可以通过类或接口的名称(一个字符串或完全限定名)来获取对应的Class对象。forName方法会触发类的初始化。
// 使用反射
Class<?> c = Class.forName("classpath.and.classname");
Object dog = c.newInstance();
Method m = c.getDeclaredMethod("bark",new Class<?>[0]);
m.invoke(dog);
在Java中,反射更接近于内省,因为你无法改变一个对象的结构。虽然一些API可以用来修改方法和属性的可见性,但并不能修改结构。 数组的反射
Integer[] nums = {1,2,3,4};
Object[] objs = nums; //这里能自动的将Integer[]转成Object[]
Object obj = nums; //Integer[]当然是一个Object
int[] ids = {1,4};
//Object[] objs2 = ids; //这里不能将int[]转换成Object[]
Object obj2 = ids; //int[] 是一个Object
上面的例子表明:基本类型的一维数组只能当做Object,而不能当作Object[]。
int[][] intArray = {{1,2},{3,4}};
Object[] oa = intArray;
Object obj = intArray;
//Integer[][] integerArray = intArray; int[][] 不是 Integer[][]
Integer[][] integerArray2 = new Integer[][]{{1,4}};
Object[][] oa2 = integerArray2;
Object[] oa3 = integerArray2;
Object obj2 = integerArray2;
从上面的例子可以看出java的二位数组是数组的数组。下面来看下对数组进行反射的例子:
package cn.zq.array.reflect;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;
public class ArrayReflect {
public static void main(String[] args) {
Random rand = new Random(47);
int[] is = new int[10];
for(int i = 0; i < is.length; i++) {
is[i] = rand.nextInt(100);
}
System.out.println(is);
System.out.println(Arrays.asList(is));
/*以上的2个输出都是输出类似"[[I@14318bb]"的字符串,
不能显示数组内存放的内容,当然我们采用遍历的方式来输出数组内的内容*/
System.out.println("--1.通过常规方式遍历数组对数组进行打印--");
for(int i = 0; i < is.length; i++) {
System.out.print(is[i] + " ");
}
System.out.println();
System.out.println("--2.通过数组反射的方式遍历数组对数组进行打印--");
Object obj = is; //将一维的int数组向上转为Object
System.out.println("obj isArray:" + obj.getClass().isArray());
for(int i = 0; i < Array.getLength(obj); i++) {
int num = Array.getInt(obj,i);
//也能通过这个常用的方法来获取对应索引位置的值
//Object value = Array.get(obj,i); //如果数组存放的是基本类型,那么返回的是基本类型对应的包装类型
System.out.print(num + " ");
}
}
}
输出: [I@14318bb [[I@14318bb] --1.通过常规方式遍历数组对数组进行打印-- 58 55 93 61 61 29 68 0 22 7 --2.通过数组反射的方式遍历数组对数组进行打印-- obj isArray:true 58 55 93 61 61 29 68 0 22 7 上面的例子首先创建了一个int的一维数组,然后随机的像里面填充0~100的整数,接着通过System.out.println()方法直接对数组输出或者用Arrays.asList方法(如果不是基本类型的一维数组此方法能按照期望转成List,如果是二维数组也不能按照我们期望转成List)将数组转成List再输出,通过都不是我们期望的输出结果。接下来以常规的数组的遍历方式来输出数组内的内容,然后将int[]看成是一个Object,利用反射来遍历其内容。Class.isArray()可以用来判断是对象是否为一个数组,假如是一个数组,那么在通过java.lang.reflect.Array这个对数组反射的工具类来获取数组的相关信息,这个类通过了一些get方法,可以用来获取数组的长度,各个版本的用来获取基本类型的一维数组的对应索引的值,通用获取值的方法get(Object array,int index),设置值的方法,还有2个用来创建数组实例的方法。通过数组反射工具类,可以很方便的利用数组反射写出通用的代码,而不用再去判断给定的数组到底是那种基本类型的数组。
package cn.zq.array.reflect;
import java.lang.reflect.Array;
public class NewArrayInstance {
public static void main(String[] args) {
Object o = Array.newInstance(int.class,20);
int[] is = (int[]) o;
System.out.println("is.length = " + is.length);
Object o2 = Array.newInstance(int.class,10,8);
int[][] iss = (int[][]) o2;
System.out.println("iss.length = " + iss.length
+ ",iss[0].lenght = " + iss[0].length);
}
}
is.length = 20
iss.length = 10,iss[0].lenght = 8
Array总共通过了2个方法来创建数组
package cn.zq.util;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Array;
public class Print {
public static void print(Object obj) {
print(obj,System.out);
}
public static void print(Object obj,PrintStream out) {
out.println(getPrintString(obj));
}
public static void println() {
print(System.out);
}
public static void println(PrintStream out) {
out.println();
}
public static void printnb(Object obj) {
printnb(obj,System.out);
}
public static void printnb(Object obj,PrintStream out) {
out.print(getPrintString(obj));
}
public static PrintStream format(String format,Object ... objects) {
return format(System.out,format,objects);
}
public static PrintStream format(PrintStream out,String format,Object ... objects) {
Object[] handleObjects = new Object[objects.length];
for(int i = 0; i < objects.length; i++) {
Object object = objects[i];
if(object == null || isPrimitiveWrapper(object)) {
handleObjects[i] = object;
} else {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bos);
printnb(object,ps);
ps.close();
handleObjects[i] = new String(bos.toByteArray());
}
}
out.format(format,handleObjects);
return out;
}
/**
* 判断给定对象是否为基本类型的包装类。
* @param o 给定的Object对象
* @return 如果是基本类型的包装类,则返回是,否则返回否。
*/
private static boolean isPrimitiveWrapper(Object o) {
return o instanceof Void || o instanceof Boolean
|| o instanceof Character || o instanceof Byte
|| o instanceof Short || o instanceof Integer
|| o instanceof Long || o instanceof Float
|| o instanceof Double;
}
public static String getPrintString(Object obj) {
StringBuilder result = new StringBuilder();
if(obj != null && obj.getClass().isArray()) {
result.append("[");
int len = Array.getLength(obj);
for(int i = 0; i < len; i++) {
Object value = Array.get(obj,i);
result.append(getPrintString(value));
if(i != len - 1) {
result.append(",");
}
}
result.append("]");
} else {
result.append(String.valueOf(obj));
}
return result.toString();
}
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Spring Boot 工程的创建和运行(图文)
- java – 将@PathParam传递给Jersey中的Sub Resource locato
- java – 我可以要求JDBCTemplate扩展一个列表参数以在一个i
- Java用jxl读取excel并保存到数据库的方法
- java – Jasper与不同应用程序之间的通信
- java – Google Glass的Hello World程序 – 逐步
- java – 在不同线程中的类之间传递对象的最佳方法?
- java – HttpURLConnection conn.getRequestProperty返回nu
- 浅谈JavaAPI 中 E 与 T 的含义
- java – 如何自定义格式化JFormattedTextField以显示IP地址
