Examples of how to use array reflection in Java programming _java

Source: Internet
Author: User
Tags arrays iterable rand reflection static class string format wrapper

What is reflection
Reflection (Reflection) enables programs that run in the JVM to detect and modify run-time behavior. "This concept is often confused with introspection (introspection), and the following is an explanation of these two terms in Wikipedia:

    • Introspection is used to detect the type of an object and the attributes it contains at run time;
    • Reflection is used to detect and modify the structure and behavior of an object at run time.
    • As can be seen from their definition, introspection is a subset of reflection. Some languages support introspection, but do not support reflection, such as C + +.

Introspection Example: The instanceof operator is used to detect whether an object belongs to a particular class.

if (obj instanceof Dog) {
  Dog d = (Dog) obj;
  D.bark ();
}

Reflection Example: the Class.forName () method can get the corresponding class object from the name of the class or interface (a string or fully qualified name). The Forname method triggers the initialization of the class.

Use reflection
class<?> c = class.forname ("Classpath.and.classname");
Object dog = C.newinstance ();
Method m = C.getdeclaredmethod ("Bark", new class<?>[0]);
M.invoke (dog);

In Java, reflection is closer to introspection because you cannot change the structure of an object. Although some APIs can be used to modify the visibility of methods and properties, they do not modify the structure.

Reflection of an array
What is the use of the reflection of an array? When do I need to use the reflection of an array? Let's take a look at the following code:

Integer[] Nums = {1, 2, 3, 4}; 
object[] Objs = nums; This can automatically convert integer[] to object[] 
object obj = Nums//integer[] is of course an Object 
int[] 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, not as object[].

Int[][] Intarray = {1, 2}, {3, 4}}; 
object[] oa = Intarray; 
Object obj = intarray; 
integer[][] Integerarray = Intarray; Int[][] is not integer[][] 
integer[][] integerArray2 = new Integer[][]{{1, 2}, {3, 4}}; 
object[][] oa2 = integerArray2; 
object[] oa3 = integerArray2; 
Object obj2 = integerArray2; 

From the example above you can see that the Java two-bit array is an array of arrays. Here's a look at the 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 (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)); /* The above 2 outputs are output similar to "[[I@14318BB]" strings, can not display the contents of the array, of course, we use the way of traversal to output the contents of the array/System.out.println ("--1." Traversing array arrays in a normal way 
    Print--"); 
    for (int i = 0; i < is.length i++) {System.out.print (Is[i] + ""); 
    } System.out.println (); 
    System.out.println ("--2.) traverse array to print by array reflection--"); Object obj = is; 
    Converts a one-dimensional int array up to object System.out.println ("obj isarray:" + obj.getclass (). IsArray ()); 
      for (int i = 0; i < array.getlength (obj); i++) {int num = array.getint (obj, i); You can also use this common method to get the value of the corresponding index//object = array.get (obj,i); 
    If the array holds the base type, then the corresponding wrapper type System.out.print (num + "") of the base type is returned; 
 } 
  } 
}

Output:

[I@14318bb 
[[I@14318BB] 
--1. The normal way to traverse an array of arrays to print- 
0 7  
--2. Iterate through array arrays to print- 
obj IsArray: True 
58 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 like inside, then passes through SYSTEM.OUT.PRINTLN () Methods direct array Output or the Arrays.aslist method (if not the basic type of one-dimensional array this method can be expected to be a list, if the two-dimensional array can not follow our expectations into a list) to the list and then output, through the output is not what we expect. The next step is to output the contents of the array in a regular array traversal, and then int[] as an object, using reflection to traverse its contents. Class.isarray () can be used to determine whether an object is an array, and if it is an array, Then, in order to get the information about the array by Java.lang.reflect.Array the tool class that is reflected by this array, this class passes some get methods, which can be used to obtain the length of the array, the values of the corresponding indexes of the one-dimensional array of the basic type, and the method of the universal fetch value. (Object array, int index), set the method for the value, and 2 methods used to create the array instance. The array reflection tool class makes it easy to use array reflection to write common code without having to judge which array is the base type.

 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, 2 
    0); 
    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 = Iss.length = ten, Iss[0].lenght = 8 

Array has a total of 2 methods to create an array
Object newinstance (class<?> componenttype, int length), which creates an array of specified lengths based on the provided Class. If the int.class is provided as above, the length is 10, equivalent to the new INT[10];
Object newinstance (class<?> componenttype, int ... dimensions) creates an array based on the Class and dimension provided. The variable parameter dimensions is used to specify the length of each dimension of an array, as in the example above, to create a two-dimensional array of new int[10][8, but you cannot create a multidimensional array with a different dimension length. With the first method of creating an array, you can create an array object o = Array.newinstance (Int[].class, 20) like this to create a two-dimensional array, which is equivalent to object o = new int[20][];
Of course, using the example above to create an array of uses is very rare, but also redundant, why not directly through new to create an array? Reflection to create an array not only the speed is not new fast, and the written program is not easy to read, but also not as direct as new. In fact, it is very rare to create an array by reflection, and what kind of abnormal requirements need to use reflection to create an array!
Because of the obstacles encountered before exporting to a primitive type of array, the following uses 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 = 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; 
   /** * Determines whether a given object is a basic type of wrapper class. 
   * @param o Given object objects * @return If it is a wrapper class of the base type, return Yes or No. 
        * * 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 (); 
 } 
}

The

Print Tool class above provides some useful static methods for outputting. and provides some overloaded versions, you can write some of the overloaded version of their own, to support the basic type of one-dimensional array printing and multidimensional array printing, look at the following print tool to test the example:

Package cn.zq.array.reflect; 
 
Import static cn.zq.util.Print.print; 
 
Import Java.io.PrintStream; 
 
Import static cn.zq.util.print.*; 
    public class Printtest {static class person {private static int counter; 
    private final int id = counter + +; 
    Public String toString () {return getclass (). Getsimplename () + ID; 
    } public static void Main (string[] args) throws Exception {print ("--printing non-array-"); 
    Print (New Object ()); 
    Print ("--printing a one-dimensional array of basic types--"); 
    Int[] is = new Int[]{1, 22, 31, 44, 21, 33, 65}; 
    print (IS); 
    Print ("--printing a two-dimensional array of basic types--"); 
    Int[][] ISS = new Int[][]{{11, 12, 13, 14}, {21, 22,}, {31, 32, 33}}; 
    Print (ISS); 
    Print ("--printing a 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); 
    Print ("--printing a two-dimensional array of non-basic types-"); person[][] Persons2 = new person[][]{{nEW person ()}, {The new person (), the New Person ()}, {The new person (), the new Person (), the new Person (),},}; 
    Print (PERSONS2); 
    Print ("--printed empty array--"); 
    Print (new int[]{}); 
    Print ("--printing an array containing null values--"); 
    Object[] objects = new object[]{new person (), NULL, New Object (), New Integer (100)}; 
    Print (objects); 
    Print ("--printing a two-dimensional array of special cases--"); 
    object[][] objects2 = new object[3][]; 
    Objects2[0] = new object[]{}; 
    OBJECTS2[2] = objects; 
    Print (OBJECTS2); 
    Print ("--output the result 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); 
     /** * There are some common methods for the Print tool class listed above, * There are some unlisted methods, please see for yourself. 
 */ 
  } 
}

Output:

--Print non-array-- 
java.lang.object@61de33- 
-Print a one-dimensional array of basic types--[1, MB, d, c 
] 
--print a two-dimensional array of basic types 
--[ One, A, [d], [A, c]] 
--Print a one-dimensional array of non-basic types-- 
[Person0, Person1, Person2, Person3, Person4, Person5, P Erson6, Person7, Person8, Person9]- 
-print two-dimensional arrays of non-basic types- 
[[Person10], [Person11, Person12], [Person13, Person14, PERSON15]] 
--Print empty array- 
[]- 
-Print an array containing null values-- 
[Person16, NULL, JAVA.LANG.OBJECT@CA0B6, 100] - 
-Print a two-dimensional array of special cases-- 
[[], NULL, [Person16, NULL, JAVA.LANG.OBJECT@CA0B6,]] 
--Output The result 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

Visible Print tool class already has the ability to print a one-dimensional array of basic types, as well as multidimensional arrays, and in general the tool class is practical to avoid having to manually write code every time you want to see the contents of the array, which is too much trouble, Later directly to the Print tool class to use the line, how convenient ah.
The tool class above does work well, but if there is a requirement: give you an array (and possibly other containers), you can give me a list. So what should we do? In fact, Arrays.aslist does not always get the results we expect, JAVA5 although generics are added, but limited, and not as generic as C + + templates, because there are basic types in Java, and even if there is a mechanism for automatic wrapping, it cannot be used with generics. The parameter type must be of a type, not a base type. Here's a workaround:

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) {R 
    Eturn 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 the original type cannot be converted in this way ArrayList list = n 
      EW 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.aslist (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 universal interface of all containers and collection interface from Iterable ( The iterator of the interface will return a iterator), so the case is handled in the Makeiterator method by one by one, and for the map type, only its entryset () method needs to be invoked for the class that implements the Iterable interface ( Collection included), Invoke iterator () to get the iterator object directly, for the enumeration type, use adapter Enumerationiterator to fit, for the array, Using array reflection to traverse an array into ArrayList, the other type calls the Arrays.aslist () method to create a list. Collectionutils also provides a number of other ways to convert, adding the methods you need to do so as needed.

Summary: The reflection of arrays provides a more convenient and flexible way of designing arrays that can be used to avoid writing cumbersome judgment statements, which pay the cost of performance and should not be reflected in arrays without the need for array reflection. Whether to use the reflection of the array, in the actual development of the beholder, according to the need to choose whether to use the reflection of the array, the best way is to use the practice to explore, first in accordance with their own thinking way to write, in practice constantly improve.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.