如何在不使用反射的情况下查看对象是否是数组?

发布于 2024-08-30 21:49:21 字数 317 浏览 6 评论 0 原文

在Java中如何在不使用反射的情况下查看对象是否是数组? 如何在不使用反射的情况下迭代所有项目?

我使用 Google GWT,所以不允许使用反射:(

我很想在不使用反射的情况下实现以下方法:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

顺便说一句:我也不想使用 JavaScript,这样我就可以在非 GWT 环境中使用它。

How can I see in Java if an Object is an array without using reflection?
And how can I iterate through all items without using reflection?

I use Google GWT so I am not allowed to use reflection :(

I would love to implement the following methods without using refelection:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

BTW: neither do I want to use JavaScript such that I can use it in non-GWT environments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一抹淡然 2024-09-06 21:49:21

您可以使用 Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

这适用于对象和基本类型数组。

对于toString,请查看Arrays.toString。您必须检查数组类型并调用适当的 toString 方法。

You can use Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

This works for both object and primitive type arrays.

For toString take a look at Arrays.toString. You'll have to check the array type and call the appropriate toString method.

胡渣熟男 2024-09-06 21:49:21

您可以使用instanceof

JLS 15.20.2 类型比较运算符 instanceof

 关系表达式:
    关系表达式引用类型实例

在运行时,如果 RelationalExpression 的值不为 nullinstanceof 运算符的结果为 true code> 并且引用可以转换为 ReferenceType,而不会引发 ClassCastException。否则结果为false

这意味着您可以执行以下操作:

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

您必须检查对象是否是 instanceof boolean[]byte[]short[]< /code>、char[]int[]long[]float[] >double[]Object[],如果您想检测所有数组类型。

此外,int[][] 是一个Object[] 实例,因此根据您想要如何处理嵌套数组,它可能会变得复杂。

对于 toStringjava.util.Arrays 有一个 toString(int[]) 和其他可以使用的重载。它还具有用于嵌套数组的deepToString(Object[])

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

它会非常重复(但即使 java.util.Arrays 非常重复),但这就是 Java 中数组的方式。

另请参阅

You can use instanceof.

JLS 15.20.2 Type Comparison Operator instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

That means you can do something like this:

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

You'd have to check if the object is an instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], or Object[], if you want to detect all array types.

Also, an int[][] is an instanceof Object[], so depending on how you want to handle nested arrays, it can get complicated.

For the toString, java.util.Arrays has a toString(int[]) and other overloads you can use. It also has deepToString(Object[]) for nested arrays.

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

It's going to be very repetitive (but even java.util.Arrays is very repetitive), but that's the way it is in Java with arrays.

See also

风为裳 2024-09-06 21:49:21

可以使用以下代码单独访问数组的每个元素:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

请注意,无需知道它是什么类型的底层数组,因为这适用于任何数组。

One can access each element of an array separately using the following code:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

Notice that it is unnecessary to know what kind of underlying array it is, as this will work for any array.

究竟谁懂我的在乎 2024-09-06 21:49:21

基本类型数组之间或基本类型数组与引用类型数组之间不存在子类型关系。请参见 JLS 4.10.3

因此,以下测试 obj 是否是任何类型的数组的测试是不正确的:

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

具体来说,如果 obj 则不起作用:是基元的一维数组。 (它确实适用于具有更高维度的原始数组,因为所有数组类型都是 Object 的子类型。但在这种情况下它没有实际意义。)

我使用 Google GWT,因此不允许我使用反射:(

最佳解决方案(问题的 isArray 数组部分)取决于什么算作“使用反射”。

  • 在 GWT 中,调用 obj.getClass().isArray() 不算使用反射1,因此这是最好的解决方案。

  • 否则,这是确定对象是否具有反射的最佳方法 。数组类型是使用一系列 instanceof 表达式。

    public boolean isArray(final Object obj) {
        返回 obj 实例对象[] || obj instanceof 布尔值[] ||
           obj实例字节[] || obj实例短[] ||
           obj 实例化 char[] || obj instanceof int[] ||
           obj实例长[] || obj实例float[] ||
           obj实例双[];
    }
    
  • 您还可以尝试如下修改对象类的名称,但对 obj.getClass() 的调用接近于反射。

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }
    

1 - 更准确地说,Class.isArray 方法rel="nofollow noreferrer">此页面

There is no subtyping relationship between arrays of primitive type, or between an array of a primitive type and array of a reference type. See JLS 4.10.3.

Therefore, the following is incorrect as a test to see if obj is an array of any kind:

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

Specifically, it doesn't work if obj is 1-D array of primitives. (It does work for primitive arrays with higher dimensions though, because all array types are subtypes of Object. But it is moot in this case.)

I use Google GWT so I am not allowed to use reflection :(

The best solution (to the isArray array part of the question) depends on what counts as "using reflection".

  • In GWT, calling obj.getClass().isArray() does not count as using reflection1, so that is the best solution.

  • Otherwise, the best way of figuring out whether an object has an array type is to use a sequence of instanceof expressions.

    public boolean isArray(final Object obj) {
        return obj instanceof Object[] || obj instanceof boolean[] ||
           obj instanceof byte[] || obj instanceof short[] ||
           obj instanceof char[] || obj instanceof int[] ||
           obj instanceof long[] || obj instanceof float[] ||
           obj instanceof double[];
    }
    
  • You could also try messing around with the name of the object's class as follows, but the call to obj.getClass() is bordering on reflection.

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }
    

1 - More precisely, the Class.isArray method is listed as supported by GWT in this page.

天涯沦落人 2024-09-06 21:49:21

您可以创建一个实用程序类来检查该类是否表示任何 CollectionMapArray

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }

You can create a utility class to check if the class represents any Collection, Map or Array

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }
笑着哭最痛 2024-09-06 21:49:21

只需obj instanceof Object[](在 JShell 上测试)。

Simply obj instanceof Object[] (tested on JShell).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文