`

java数组反射

 
阅读更多

数组反射

如果因为某种原因,您并不确定参数或对象是不是数组,您可以检索对象的 Class 对象并询问它。 Class 类的 isArray() 方法将会告诉您。一旦您知道拥有了一个数组,您可以询问 Class 的 getComponentType() 方法,您实际拥有的是什么类型的数组。如果 isArray() 方法返回 false,那么 getComponentType() 方法返回空。否则返回元素的 Class 类型。如果数组是多维的,您可以递归调用 isArray() 。它将仍只包含一个 component 类型。此外,您可以用在 java.lang.reflect 包里找到的 Array 类的 getLength() 方法获取数组的长度。

为了演示,清单 2-3 显示了传递给 main() 方法的参数是 java.lang.String 对象的数组,其中数组长度由命令行参数的个数确定:


清单 2-3. 使用反射检查数组类型和长度

 

public class ArrayReflection {
  public static void main (String args[]) {
    printType(args);
  }
  private static void printType (Object object) {
    Class type = object.getClass();
    if (type.isArray()) {
      Class elementType = type.getComponentType();
      System.out.println("Array of: " + elementType);
      System.out.println(" Length: " + Array.getLength(object));
    }
  }
}
 

注意:如果 printType() 用于前面定义的 buttons 和 components 变量调用,每个都会表明数组是 java.awt.Button 类型。

如果不使用 isArray() 和 getComponentType() 方法,而且试图打印数组的 Class 类型,您将获得一个包含 [ ,后面跟着一个字母和类名(如果是个基本数据类型就没有类名)的字符串。例如,如果您试图打印出上述 printType() 方法中的类型变量,您将获得 class [Ljava.lang.String; 作为输出。

除了询问一个对象是不是数组以及是什么类型的数组之外,您还可以在运行时用 java.lang.reflect.Array class 创建数组。这对于创建一般实用例程非常有用,这些例程执行数组任务,比如将大小加倍。(我们会立即回到那一点。)

要创建一个新数组,使用 Array 的 newInstance() 方法,它有两种变化形式。对于一维数组您通常将使用较简单版本,它的执行方式如语句 new type [length] 所示,并作为对象返回数组: public static Object newInstance(Class type, int length) 。例如,下面的代码创建一个五个整数空间大小的数组:

int array[] = (int[])Array.newInstance(int.class, 5);
 

注意:要为基本数据类型指定 Class 对象,只要在基本数据类型名末尾添加 .class 就可以了。您还可以使用包装类中的 TYPE 变量,如 Integer.TYPE。

newInstance() 方法中的第二种变化形式要求维数被指定为整型数组: public static Object newInstance(Class type,int dimensions []) 。在创建一个一维数组的最简单的情况下,您将创建只有一个元素的数组。换句话说,如果您要创建包含五个整数的相同数组,您需要创建一个单个元素 5 的数组并传递到 newInstance() 方法,而不是传递整数值 5。

int dimensions[] = {5};
int array[] = (int[])Array.newInstance(int.class, dimensions);

 在您只需要创建一个矩形数组的时候,您就可以将每个数组长度填充到这个 dimensions 数组中。例如,下面的代码与创建一个 3 X 4 的整数数组等价。

int dimensions[] = {3, 4};
int array[][] = (int[][])Array.newInstance(int.class, dimensions);

 但是,如果您需要创建一个非矩形数组,您将需要多次调用 newInstance() 方法。第一次调用将定义外部数组的长度,并获得一个看上去很古怪的类参数([].class 适用于元素为 float 类型的数组)。每个后续调用将定义每个内部数组的长度。例如,下面演示了如何创建一个元素为 float 类型的数组,其内部数组的大小设置像一组保龄球瓶:第一排一个元素,第二排两个,第三排三个,第四排四个。为了帮您将这种情况形象化,让我们回顾早先在图 2-4 展示的三角形数组。

float bowling[][] = (float[][])Array.newInstance(float[].class, 4);
for (int i=0; i<4; i++) {
  bowling[i] = (float[])Array.newInstance(float.class, i+1);
}
 

一旦在运行时创建了数组,您还可以获取和设置数组元素。不过通常不会这样做,除非键盘上的方括号键失灵或者您在动态的编程环境(程序被创建时数组名 未知)中工作。 如表 2-2 所示, Array 类有一系列的 getter 和 setter 方法用来获取和设置数组元素。使用什么方法取决于您处理的数组类型。

表 2-2. 数组 getter 和 setter 方法

Getter 方法  Setter 方法 

get(Object array, int index) set(Object array, int index, Object value)
getBoolean(Object array, int index) setBoolean(Object array, int index, boolean value)
getByte(Object array, int index) setByte(Object array, int index, byte value)
getChar(Object array, int index) setChar(Object array, int index, char value)
getDouble(Object array, int index) setDouble(Object array, int index, double value)
getFloat(Object array, int index) setFloat(Object array, int index, float value)
getInt(Object array, int index) setInt(Object array, int index, int value)
getLong(Object array, int index) setLong(Object array, int index, long value)
getShort(Object array, int index) setShort(Object array, int index, short value) 

 注意:您可以一直使用 get() 和 set() 方法。如果数组是一个基本数据类型数组, get() 方法的返回值或 set() 方法的值参数将被包装到用于基本数据类型的包装类中,像装着一个 int 数组的 Integer 类那样。

清单 2-4 提供了一个如何创建、填充以及显示数组信息的完整示例。方括号只在 main() 方法的声明中使用。


清单 2-4. 使用反射创建、填充和显示数组

import java.lang.reflect.Array;
import java.util.Random;
public class ArrayCreate {
  public static void main (String args[]) {
    Object array = Array.newInstance(int.class, 3);
    printType(array);
    fillArray(array);
    displayArray(array);
  }
  private static void printType (Object object) {
    Class type = object.getClass();
    if (type.isArray()) {
      Class elementType = type.getComponentType();
      System.out.println("Array of: " + elementType);
      System.out.println("Array size: " + Array.getLength(object));
    }
  }
  private static void fillArray(Object array) {
    int length = Array.getLength(array);
    Random generator = new Random(System.currentTimeMillis());
    for (int i=0; i<length; i++) {
      int random = generator.nextInt();
      Array.setInt(array, i, random);
    }
  }
  private static void displayArray(Object array) {
    int length = Array.getLength(array);
    for (int i=0; i<length; i++) {
      int value = Array.getInt(array, i);
      System.out.println("Position: " + i +", value: " + value);
    }
  }
}

 运行时,输出将如下所示(尽管随机数会不同):

Array of: int
Array size: 3
Position: 0, value: -54541791
Position: 1, value: -972349058
Position: 2, value: 1224789416
 

让我们返回到早先的,创建一个将数组大小加倍的方法的示例。既然您知道如何获取数组的类型,您可以创建一种方法用来将任意类型数组的大小加倍。这个方法确保我们能在获取它的长度和类型之前得到数组。然后在复制原来的那组元素之前,它将新数组的大小加倍。

 

static Object doubleArray(Object original) {
  Object returnValue = null;
  Class type = original.getClass();
  if (type.isArray()) {
    int length = Array.getLength(original);
    Class elementType = type.getComponentType();
    returnValue = Array.newInstance(elementType, length*2);
    System.arraycopy(original, 0, returnValue, 0, length);
  }
  return returnValue;
}
 
分享到:
评论

相关推荐

    java 反射中操作数组

    本文将详细解释如何在Java反射中操作数组。 首先,我们创建一个字符串数组`String[] sArr = {}`。要获取这个数组的`Class`对象,我们可以调用`getClass()`方法,即`Class css = sArr.getClass();`。这个`Class`对象...

    怎样用Jvm处理Java数组.doc

    ### 如何理解Java数组在JVM中的处理方式 在探讨如何使用JVM处理Java数组之前,我们首先需要明确几个概念。Java数组本质上是一种特殊的对象,它具有固定长度,并且存储同种类型的元素。本文将围绕Java数组的一些核心...

    实例讲解Java编程中数组反射的使用方法

    数组反射在处理数组时特别有用,因为Java的数组具有特定的特性。例如,一个基本类型的数组(如`int[]`)不能被赋值给`Object[]`,而引用类型的数组(如`Integer[]`)可以。这是因为基本类型数组实际上是对象,但它们...

    详解java中反射机制(含数组参数)

    Java 中的反射机制(含数组参数) Java 中的反射机制是一种强大的工具,可以在运行时获取类的内部信息,包括modifiers、superclass、interfaces、fields 和 methods 的所有信息,并可以在运行时改变 fields 的内容...

    Java数组练习题(带答案).doc

    本文将围绕Java数组进行详细介绍,并辅以示例来加深理解。 首先,我们要了解数组的访问机制。数组是一种线性数据结构,其元素通过整数索引进行访问。数组在声明时需要指定元素类型和数组大小,一旦创建完成,其长度...

    java反射全解(反射原理+反射API详解+反射与数组+反射与泛型+反射源码与性能开销+反射优缺点+反射与内省)

    数组是 Java 语言中的一种基本数据结构,反射机制可以动态地获取数组的信息和调用数组的方法。 反射与泛型是指在反射机制中如何操作泛型。泛型是 Java 语言中的一种类型参数机制,反射机制可以动态地获取泛型的信息...

    Java方法反射调用demo

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有了高度的灵活性,常用于框架开发、插件系统、元编程等...

    Java技术对接收数组参数的成员方法进行反射

    总的来说,理解和掌握如何使用Java反射调用接收数组参数的方法,将有助于提升你在面对复杂编程问题时的灵活性和应变能力。通过实践和不断学习,你可以更熟练地运用反射技术,从而在编程中实现更多可能性。

    java--数组.txt

    ### Java数组深度解析 在Java编程语言中,数组是一种非常基础且重要的数据结构,它能够存储固定数量的同类型元素。对于初学者来说,经常会听到这样一句话:“Java是一门纯粹的面向对象的语言,其数组也是一种对象。...

    java 通过反射获取枚举类,及枚举类的值,枚举类枚举实例名

    在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法等对象。枚举(Enumeration)是Java中的一个特殊类类型,用于定义一组常量。本项目"test-enum-demo-...

    java反射机制学习(四):通过反射执行方法、操作属性、操作数组中的数据

    Java反射机制是Java编程语言中一个强大的特性,它允许运行时动态地获取类的信息并进行操作,如创建对象、调用方法、访问属性以及处理数组等。在本篇讲解中,我们将深入理解如何通过反射来执行方法、操作属性以及处理...

    java反射-英文版反射规范

    - Java反射能够创建和操作数组,无论数组元素是什么类型。 - 可以创建一维或多维数组,并通过反射获取数组的长度和元素。 ##### 2. **修饰符类** - 通过反射可以获取到字段、方法或构造器的访问权限修饰符。 - ...

    Java 反射封装 JavaBean

    使用 Java 反射封装 JavaBean &lt;br&gt; 说明:这个程序在没有使用Hiberante时挺有用的 需要一个数据库查询语句 对应的JavaBean的全名(现在是Class,原来Class.getName()) 返回List包含多个JavaBean

    java的反射机制pdf

    ### Java的反射机制详解 #### 一、引言 反射机制是Java编程语言的重要特性之一,它为开发者提供了强大的灵活性,使得程序可以在运行时动态地获取类的信息,并且可以动态地调用对象的方法。这对于很多高级应用来说...

    java主要反射和内存机制

    Java是一种广泛使用的面向对象的编程语言,其强大的特性之一就是反射和内存管理机制。这篇文档将深入探讨这两个关键概念。 **一、Java反射机制** Java反射机制是Java提供的一种能够在运行时检查类、接口、字段和...

    java反射经典实例

    Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在本“Java反射经典实例”中,我们将深入探讨这个主题,了解如何利用反射来访问和修改私有属性以及...

    java反射知识点

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 我的代码里主要有一下知识点: 1.获取Class对象的三种方式 2.获取构造方法并调用 3.获取成员方法 4.获取成员变量 5.反射数组 6.通过反射...

    Java反射机制笔记(简单易懂)

    在Java中,我们可以使用反射机制来操作数组。我们可以使用Array类来创建和操作数组。 例如: ```java Array array = Array.newInstance(String.class, 5); array.set(0, "hello"); array.set(1, "world"); ``` 总结...

    java 通过反射获取类上注解,方法上注解,注解里的值及方法参数

    反射(Reflection)是Java的一个强大特性,允许程序在运行时检查类、接口、字段和方法等信息。本教程将深入探讨如何通过反射获取类、方法上的注解以及注解中的值和方法参数。 1. **注解的定义与使用** 注解以`@`...

Global site tag (gtag.js) - Google Analytics