Java Tutorial/Reflection/Array

Материал из Java эксперт
Перейти к: навигация, поиск

Array reflection and two dimensional array

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import static java.lang.System.out;
import java.lang.reflect.Array;
public class CreateMatrix {
  public static void main(String... args) {
    Object matrix = Array.newInstance(int.class, 2, 2);
    Object row0 = Array.get(matrix, 0);
    Object row1 = Array.get(matrix, 1);
    Array.setInt(row0, 0, 1);
    Array.setInt(row0, 1, 2);
    Array.setInt(row1, 0, 3);
    Array.setInt(row1, 1, 4);
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        out.format("matrix[%d][%d] = %d%n", i, j, ((int[][]) matrix)[i][j]);
  }
}





class name for double and float array

class ClassInfoDemo2 {
  public static void main(String[] args) {
    Class c = String.class;
    System.out.println(c.getName());
    c = ClassInfoDemo2.class;
    System.out.println(c.getName());
    c = double.class;
    System.out.println(c.getName());
    c = float[].class;
    System.out.println(c.getName());
  }
}





Create array with Array.newInstance

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import static java.lang.System.out;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ArrayCreator {
  private static String s = "java.math.BigInteger bi[] = { 123, 234, 345 }";
  private static Pattern p = Pattern
      .rupile("^\\s*(\\S+)\\s*\\w+\\[\\].*\\{\\s*([^}]+)\\s*\\}");
  public static void main(String... args) {
    Matcher m = p.matcher(s);
    if (m.find()) {
      String cName = m.group(1);
      String[] cVals = m.group(2).split("[\\s,]+");
      int n = cVals.length;
      try {
        Class<?> c = Class.forName(cName);
        Object o = Array.newInstance(c, n);
        for (int i = 0; i < n; i++) {
          String v = cVals[i];
          Constructor ctor = c.getConstructor(String.class);
          Object val = ctor.newInstance(v);
          Array.set(o, i, val);
        }
        Object[] oo = (Object[]) o;
        out.format("%s[] = %s%n", cName, Arrays.toString(oo));
        // production code should handle these exceptions more gracefully
      } catch (ClassNotFoundException x) {
        x.printStackTrace();
      } catch (NoSuchMethodException x) {
        x.printStackTrace();
      } catch (IllegalAccessException x) {
        x.printStackTrace();
      } catch (InstantiationException x) {
        x.printStackTrace();
      } catch (InvocationTargetException x) {
        x.printStackTrace();
      }
    }
  }
}





Create integer array with Array.newInstance

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import static java.lang.System.out;
import java.lang.reflect.Array;
public class ArrayTrouble {
  public static void main(String... args) {
    Object o = Array.newInstance(int.class, 0);
    int[] i = (int[]) o;
    int[] j = new int[0];
    out.format("i.length = %d, j.length = %d, args.length = %d%n", i.length,
        j.length, args.length);
    Array.getInt(o, 0); // ArrayIndexOutOfBoundsException
  }
}





Demonstrates the use of the Array class

/*
 *     file: ArrayDemo.java
 *  package: oreilly.hcj.reflection
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

import java.lang.reflect.Array;
/**  
 * Demonstrates the use of the Array class.
 *
 * @author 
 * @version $Revision$
 */
public class ArrayDemo {
  /** 
   * Copy an array and return the copy.
   *
   * @param input The array to copy.
   *
   * @return The coppied array.
   *
   * @throws IllegalArgumentException If input is not an array.
   */
  public static Object copyArray(final Object input) {
    final Class type = input.getClass();
    if (!type.isArray()) {
      throw new IllegalArgumentException();
    }
    final int length = Array.getLength(input);
    final Class componentType = type.getComponentType();
    final Object result = Array.newInstance(componentType, length);
    for (int idx = 0; idx < length; idx++) {
      Array.set(result, idx, Array.get(input, idx));
    }
    return result;
  }
  /** 
   * Run the demo.
   *
   * @param args Command line arguments (ignored).
   */
  public static void main(final String[] args) {
    try {
      int[] x = new int[] { 2, 3, 8, 7, 5 };
      char[] y = new char[] { "a", "z", "e" };
      String[] z = new String[] { "Jim", "John", "Joe" };
      System.out.println(" -- x and y --");
      outputArrays(x, y);
      System.out.println(" -- x and copy of x --");
      outputArrays(x, copyArray(x));
      System.out.println(" -- y and copy of y --");
      outputArrays(y, copyArray(y));
      System.out.println(" -- z and copy of z --");
      outputArrays(z, copyArray(z));
    } catch (final Exception ex) {
      ex.printStackTrace();
    }
  }
  /** 
   * Print out 2 arrays in columnar format.
   *
   * @param first The array for the first column.
   * @param second The array for the second column.
   *
   * @throws IllegalArgumentException __UNDOCUMENTED__
   */
  public static void outputArrays(final Object first, final Object second) {
    if (!first.getClass()
              .isArray()) {
      throw new IllegalArgumentException("first is not an array.");
    }
    if (!second.getClass()
               .isArray()) {
      throw new IllegalArgumentException("second is not an array.");
    }
    final int lengthFirst = Array.getLength(first);
    final int lengthSecond = Array.getLength(second);
    final int length = Math.max(lengthFirst, lengthSecond);
    for (int idx = 0; idx < length; idx++) {
      System.out.print("[" + idx + "]\t");
      if (idx < lengthFirst) {
        System.out.print(Array.get(first, idx) + "\t\t");
      } else {
        System.out.print("\t\t");
      }
      if (idx < lengthSecond) {
        System.out.print(Array.get(second, idx) + "\t");
      }
      System.out.println();
    }
  }
}
/* ########## End of File ########## */





Determining If an Object Is an Array

public class Main {
  public static void main(String[] argv) throws Exception {
    boolean b = "".getClass().isArray();
    if (b) {
      System.out.println("object is an array");
    }
  }
}





Getting the Component Type of an Array Object

public class Main {
  public static void main(String[] argv) throws Exception {
    Object o = new int[1][2][3];
    o.getClass().getComponentType();
  }
}





Getting the Length and Dimensions of an Array Object

import java.lang.reflect.Array;
public class Main {
  public static void main(String[] argv) throws Exception {
    Object o = new int[1][2][3];
    int len = Array.getLength(o); // 1
    System.out.println(len);
    int dim = getDim(o); // 3
    System.out.println(dim);
  }
  public static int getDim(Object array) {
    int dim = 0;
    Class cls = array.getClass();
    while (cls.isArray()) {
      dim++;
      cls = cls.getComponentType();
    }
    return dim;
  }
}





Is field an array

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import static java.lang.System.out;
import java.lang.reflect.Field;
public class ArrayFind {
  public static void main(String... args) {
    boolean found = false;
    try {
      Class<?> cls = Class.forName(args[0]);
      Field[] flds = cls.getDeclaredFields();
      for (Field f : flds) {
        Class<?> c = f.getType();
        if (c.isArray()) {
          found = true;
          out.format("%s%n" + "           Field: %s%n"
              + "            Type: %s%n" + "  Component Type: %s%n", f, f
              .getName(), c, c.getComponentType());
        }
      }
      if (!found) {
        out.format("No array fields%n");
      }
      // production code should handle this exception more gracefully
    } catch (ClassNotFoundException x) {
      x.printStackTrace();
    }
  }
}





Returns the length of the specified array, can deal with Object arrays and with primitive arrays.

/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

import java.lang.reflect.Array;

/**
 * Operations on arrays, primitive arrays (like <code>int[]</code>) and
 * primitive wrapper arrays (like <code>Integer[]</code>).
 * 
 * This class tries to handle <code>null</code> input gracefully.
 * An exception will not be thrown for a <code>null</code>
 * array input. However, an Object array that contains a <code>null</code>
 * element may throw an exception. Each method documents its behaviour.
 *
 * @author Stephen Colebourne
 * @author Moritz Petersen
 * @author 
 * @author Maarten Coene
 * @since 2.0
 * @version $Id: ArrayUtils.java 632503 2008-03-01 00:21:52Z ggregory $
 */
public class Main {
  //-----------------------------------------------------------------------
  /**
   * Returns the length of the specified array.
   * This method can deal with <code>Object</code> arrays and with primitive arrays.
   *
   * If the input array is <code>null</code>, <code>0</code> is returned.
   *
   * <pre>
   * ArrayUtils.getLength(null)            = 0
   * ArrayUtils.getLength([])              = 0
   * ArrayUtils.getLength([null])          = 1
   * ArrayUtils.getLength([true, false])   = 2
   * ArrayUtils.getLength([1, 2, 3])       = 3
   * ArrayUtils.getLength(["a", "b", "c"]) = 3
   * </pre>
   *
   * @param array  the array to retrieve the length from, may be null
   * @return The length of the array, or <code>0</code> if the array is <code>null</code>
   * @throws IllegalArgumentException if the object arguement is not an array.
   * @since 2.1
   */
  public static int getLength(Object array) {
      if (array == null) {
          return 0;
      }
      return Array.getLength(array);
  }
}





Use Array.setInt to fill an array

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import static java.lang.System.err;
import java.lang.reflect.Array;
public class ArrayTroubleAgain {
  public static void main(String... args) {
    Integer[] ary = new Integer[2];
    try {
      Array.setInt(ary, 0, 1); // IllegalArgumentException
      // production code should handle these exceptions more gracefully
    } catch (IllegalArgumentException x) {
      err.format("Unable to box%n");
    } catch (ArrayIndexOutOfBoundsException x) {
      x.printStackTrace();
    }
  }
}





Use Array.setShort and Array.setLong

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.lang.reflect.Array;
public class ArrayTroubleToo {
  public static void main(String... args) {
    Object o = new int[2];
    Array.setShort(o, 0, (short) 2); // widening, succeeds
    Array.setLong(o, 1, 2L); // narrowing, fails
  }
}