What is the use of reflection in arrays? When do you need to use an array of reflections? First look at the following code:
Integer[] Nums = {1, 2, 3, 4};object[] Objs = nums;//This can automatically turn integer[] into object[]object obj = nums;//integer[] Of course it's a objecti. nt[] ids = {1, 2, 3, 4};//object[] objs2 = IDs;//This cannot convert int[] to object[]object obj2 = IDs;//int[] is an Object
The above example shows that a one-dimensional array of basic types can only be used as object and not as object[].
Int[][] Intarray = {{1, 2}, {3, 4}};object[] oa = Intarray;object obj = intarray;//integer[][] Integerarray = Intarray; in T[][] not integer[][]integer[][] integerArray2 = new Integer[][]{{1, 2}, {3, 4}};object[][] oa2 = integerarray2;object[] Oa 3 = Integerarray2;object Obj2 = integerArray2;
As you can see from the above example, the two-bit array of Java is an array of arrays. Here's an example of a reflection of an array:
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 (; int[] is = new int[10]; for (int i = 0; i < is.length; i++) { is[i] = Rand.nextin T (+); } system.out.println (IS); system.out.println (Arrays.aslist (IS)); /* All 2 of the above outputs are strings that resemble "[[[[[[]]]" email protected cannot display the contents of an array. Of course, we use the traversal to output the contents of the array */ system.out.println ("--1. to traverse an array of arrays in the usual way to print--"); for (int i = 0; i < is.length; i++) { system.out.print (is[i] + ""); } system.out.println (); System.out.println ("--2. to traverse an array of arrays by array reflection to print--"); object obj = is; Convert the one-dimensional int array upward to object system.out.println ("obj isarray:" + obj.getclass (). IsArray ()); for (int i = 0; i < array.getlength (obj); i++) { &NBSP;&NB sp; int num = array.getint (obj, i); & Nbsp;//can also use this common method to obtain the value of the corresponding index location //object value = Array.get (obj , i); If the array holds the base type, then the package type for the base type is returned system.out.print (num + "") ; } }}
Output:
[Email Protected][[[email protected]]--1. Iterates through an array of arrays in the usual way--58 55 93 61 61 29 68 0 22 7--2. Iterating through an array of arrays in an array of arrays to print--obj IsA RRAY:TRUE58 55 93 61 61 29 68 0 22 7
The above example first creates a one-dimensional array of int, then randomly fills the 0~100 integer with the System.out.println () method, and then outputs the array directly using the Arrays.aslist method (
if it is not a one-dimensional array of primitive types this method can be converted to list as expected, and if it is a two-dimensional array, it cannot be converted to a list as we wish .The array is converted to a list and then output, which is not the output we expect. The next step is to output the contents of the array in a regular array traversal, then int[] as an object, using reflection to traverse its contents. Class.isarray () can be used to determine whether an object is an array, if it is an array, So, in order to get the information about the array by Java.lang.reflect.Array the tool class that is reflected by this group, this class passes through some get methods, which can be used to get the length of the array, the value of the corresponding index of each version of the one-dimensional array to get the basic type, and the method of getting the value of the universal get (Object array, int index), the method for setting the value, and 2 methods for creating an array instance. By using the array reflection tool class, it is convenient to use the array reflection to write out the common code without having to judge the type of array that the given array is.
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); int[] is = (int[]) o; System.out.println ("is.length =" + is.length), Object O2 = Array.newinstance (Int.class, 8); int[][] iss = (int[][]) O2; System.out.println ("iss.length =" + Iss.length + ", Iss[0].lenght =" + Iss[0].length);}}
Is.length = 20iss.length = ten, Iss[0].lenght = 8
Array has a total of 2 methods to create arrays
- Object newinstance (class<?> componenttype, int length), creates an array of the specified length according to the Class provided. If the int.class is provided as above, the length is 10, which is equivalent to new int[10];
- Object newinstance (class<?> componenttype, int ... dimensions), creates an array based on the provided Class and dimension, and the variable parameter dimensions is used to specify the length of each dimension of the array , as in the example above, is equivalent to creating a two-dimensional array of new int[10][8], but you cannot create multidimensional arrays with different lengths of each dimension. Using the first method of creating an array, you can create an array like this, object o = Array.newinstance (Int[].class, 20) can be used to create a two-dimensional array, which is equivalent to object o = new int[20][];
Of course, the use of the above example to create arrays is very rare, but also superfluous, why not directly through new to create an array? Reflection creates an array not only the speed is not new fast, but also the writing program is not easy to read, but not as new comes directly. The fact that arrays are created by reflection is really rare, and what kind of perverted demand needs to be reflected to create arrays!
Because of the obstacles encountered when outputting an array of primitive types, the following will use array reflection to implement a tool class to achieve the desired output:
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 | | isprimitivewra Pper (object)) {Handleobjects[i] = object;} else {Bytearrayoutputstream bos = new BYTEARRAYOUTPUtstream (); PrintStream PS = new PrintStream (BOS);p RINTNB (object, PS);p s.close (); handleobjects[i] = new String (Bos.tobytearray ());}} Out.format (format, handleobjects); return out;} /** * Determines whether a given object is a basic type of wrapper class. * @param o Given object * @return if it is a wrapper class of the base type, return yes, otherwise return No. */private Static Boolean isprimitivewrapper (Object o) {return o instanceof Void | | o instanceof boolean| | o instanceof Cha Racter | | 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 ();}}
The Print tool class above provides some useful static methods for output, and provides some overloaded versions that can be used to write some overloaded versions of your own, support the printing of basic types of one-dimensional arrays and the printing of multidimensional arrays, and see the following example of the Print tool testing:
Package Cn.zq.array.reflect;import static Cn.zq.util.print.print;import java.io.printstream;import static cn.zq.util.print.*;p Ublic class Printtest {static class person {private static int counter;private final INT id = counter + +;p ublic String toString () {return getclass (). Getsimplename () + ID;}} public static void Main (string[] args) throws Exception {print ("--print non-array--");p rint (New Object ());p rint ("--print one-dimensional array of the base type-- "); int[] is = new Int[]{1, n, D, D, a, 12};p rint (IS);p rint ("--printing a two-dimensional array of basic types-"); int[][] iss = new INT[][]{{11, 1 3, 14},{21, 22,},{31, Rint}};p (ISS);p rint ("-Print one-dimensional array of non-basic types--"); person[] persons = new Person[10];for (int i = 0; i < persons.length; i++) {persons[i] = new Person ();} Print (persons);p rint ("-Prints a two-dimensional array of non-basic types--"); person[][] Persons2 = new person[][]{{new person ()},{new person (), new person ()},{new person (), new Person (), new person () ,},};p rint (persons2);p rint ("--Print empty array--");p rint (New int[]{});p rint ("-Print an array with null values-"); object[] objects = new Object[]{new PErson (), NULL, new Object (), new Integer};p rint (objects);p rint ("--printing a two-dimensional array of special cases-"); object[][] Objects2 = new Object [3] [];objects2[0] = new Object[]{};objects2[2] = Objects;print (objects2);p rint ("--output the results of a one-dimensional array to a file--"); PrintStream out = new PrintStream ("out.c"); try {print (ISS, out);} finally {out.close ();} Print ("--formatted output--"), Format ("%-6d%s%B%s", 10086, "is", true, ISS);/** * Some of the most common methods of the print tools class are listed above, * There are some methods that are not listed, please check them yourself. */}}
Output:
--Print non-array--[email protected]--print a one-dimensional array of basic types--[1, 22, 31, 44, 21, 33, 65]--print two-dimensional arrays of basic types--[[11, 12, 13, 14], [21, 22], [31, 32, 3 3]]--Printing non-basic types of one-dimensional arrays--[person0, Person1, Person2, Person3, Person4, Person5, Person6, Person7, Person8, person9]-- Print a two-dimensional array of non-basic types--[[person10], [Person11, Person12], [Person13, Person14, person15]]--print empty array--[]--print an array containing null values--[ Person16, NULL, [email protected], 100]--printing a two-dimensional array of special cases--[[], NULL, [Person16, NULL, [email protected], 100]]-- Outputs the results of a one-dimensional array to a file----formatted output--10086 is TRUE [[11, 12, 13, 14], [21, 22], [31, 32, 33]
Output file:
The Print tool class already has the ability of printing the basic type of a one-dimensional array and multidimensional arrays, the overall tool class is very practical, so that every time you want to see the contents of the array has manual to write code, that is too troublesome, and then directly to the print tool class to take the past with the line, What a convenience.
The tool class above does work well, but if there is a need to give you an array (and possibly other containers), you can give me a list. So what should we do? In fact, arrays.aslist not always get the results we expect, JAVA5 although the generics are added, but there is a limit, and can not be as common as C + + template, it is because there is a basic type in Java, even if there is a mechanism for automatic packaging, with generics and can not be used, The parameter type must be of a certain type, not a base type. Here's a solution for you:
Package Cn.zq.util;import Java.lang.reflect.array;import Java.util.arraylist;import java.util.arrays;import Java.util.enumeration;import Java.util.iterator;import Java.util.list;import Java.util.map;public class collectionutils {public static list<?> aslist (Object obj) {return converttolist (Makeiterator (obj));} public static <T>List<T> converttolist (iterator<t> Iterator) {if (Iterator = = null) {return null;} list<t> list = new arraylist<t> (), while (Iterator.hasnext ()) {List.add (Iterator.next ());} return list;} @SuppressWarnings ({"Rawtypes", "Unchecked"}) public static iterator<?> makeiterator (Object obj) {if (obj Instanceof Iterator) {return (iterator<?>) obj;} if (obj = = null) {return null;} if (obj instanceof Map) {obj = ((map<?,? >) obj). EntrySet ();} iterator<?> Iterator = null;if (obj instanceof iterable) {Iterator = ((iterable<?>) obj). Iterator ();} else if ( Obj.getclass (). IsArray ()) {//object[] Objs = (object[]) obj;//An array of primitive types cannot beThis translates ArrayList list = new ArrayList (array.getlength (obj)), for (int i = 0; i < array.getlength (obj); i++) {List.add (Array). Get (obj, i));} iterator = List.iterator ();} else if (obj Instanceof enumeration) {iterator = new Enumerationiterator ((enumeration) obj);} else {iterator = Arrays.aslis T (obj). iterator ();} return iterator;} public static class Enumerationiterator<t> implements Iterator<t> {private enumeration<t> Enumeration;public Enumerationiterator (Enumeration<t> enumeration) {This.enumeration = enumeration;} public Boolean Hasnext () {return enumeration.hasmoreelements ();} Public T Next () {return enumeration.nextelement ();} public void Remove () {throw new Unsupportedoperationexception ();}}}
Test code:
Package Cn.zq.array.reflect;import Java.util.iterator;import Java.util.list;import Cn.zq.array.reflect.printtest.person;import Cn.zq.util.collectionutils;public class CollectionUtilsTest {public static void Main (string[] args) {System.out.println ("--basic type one-dimensional array--"); int[] Nums = {1, 3, 5, 7, 9}; list<?> list = Collectionutils.aslist (nums); SYSTEM.OUT.PRINTLN (list); System.out.println ("--non-basic type one-dimensional array--"); person[] persons = new person[]{new person (), new Person (), new Person (),}; List<person> personlist = (list<person>) collectionutils.aslist (persons); System.out.println (personlist); System.out.println ("--iterator--");iterator<person> Iterator = Personlist.iterator (); List<person> personList2 = (list<person>) collectionutils.aslist (iterator); System.out.println (PERSONLIST2);}}
Output:
--Basic type one-dimensional array--[1, 3, 5, 7, 9]--non-basic type one-dimensional array--[person0, Person1, Person2]--iterator--[person0, Person1, Person2]
In the Java Container Class library can be divided into collection,map, arrays, because iterator (as well as the early legacy Interface enumeration) is the common interface of all containers and collection interface from Iterable ( The iterator of the interface will return a iterator), so one by one of these scenarios are handled in the Makeiterator method, and only the EntrySet () method is required for the map type, for classes that implement the Iterable interface ( Collection is included), call iterator () to get the iterator object directly, for the enumeration type, with adapter enumerationiterator for adaptation, for arrays, Use array reflection to traverse the array into ArrayList, and for other types call the Arrays.aslist () method to create a list. Collectionutils also provides some other ways to convert and add the methods you need as needed.
Summary: The reflection of an array provides a more convenient and flexible way to design an array that might occur, so as not to write those more troublesome judgments, the flexibility to pay is the cost of performance, and the reflection of arrays in cases where arrays are not needed at all is not expected. Whether to use the reflection of the array, in the actual development of the beholder benevolent see, according to the need to choose whether to use the array of reflection, the best way is to use the practice to explore, first in accordance with the way you think to write, in the practice of continuous improvement.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
A probe into the reflection of arrays in Java